/* Story comforts (v6.40): reading preferences, speech colour, the Retry
   dialog, the Latest button, the entry menu under Voice entries, the edit
   bar, and change dots on the panel tabs. Tokens from tokens.css. */

/* Reading preferences (Settings → Reading). src/ui/reading.mjs sets
   data-reading-* on the page root and on the preview line in Settings. */
:root{--read-scale:1;--read-leading:1.6;--read-measure:820px;--read-font:var(--body)}
[data-reading-size=small]{--read-scale:.9}
[data-reading-size=standard]{--read-scale:1}
[data-reading-size=large]{--read-scale:1.12}
[data-reading-size=larger]{--read-scale:1.25}
[data-reading-spacing=compact]{--read-leading:1.4}
[data-reading-spacing=standard]{--read-leading:1.6}
[data-reading-spacing=airy]{--read-leading:1.85}
[data-reading-width=narrow]{--read-measure:640px}
[data-reading-width=standard]{--read-measure:820px}
[data-reading-width=wide]{--read-measure:1120px}
[data-reading-font=serif]{--read-font:var(--body)}
[data-reading-font=sans]{--read-font:"Work Sans",sans-serif}
@media(min-width:1200px){:root:not([data-reading-width]),[data-reading-width=standard]{--read-measure:900px}}
@media(max-width:480px){:root:not([data-reading-spacing]),[data-reading-spacing=standard]{--read-leading:1.55}}
.message{max-width:var(--read-measure);line-height:var(--read-leading);font-family:var(--read-font)}
.message:not(.notice){font-size:calc(var(--read-scale) * 1em)}
.reading-preview{margin:0;padding:12px 14px;border:1px solid var(--stone-850);border-radius:var(--radius-md);background:var(--bg);color:var(--text-dim);font-family:var(--read-font);font-size:calc(var(--read-scale) * var(--size-story));line-height:var(--read-leading)}
@media(max-width:800px){.reading-preview{font-size:calc(var(--read-scale) * var(--size-lead))}}
/* Speech: the story's prose reads in a light grey and quoted words
   (src/ui/speech.mjs) stand out in the body text's white, in the narration
   and the player's own lines; notices and turn summaries keep their own. */
.message.assistant>p{color:var(--text-dim)}
.message:not(.notice) .speech,.reading-preview .speech{color:var(--text)}

/* The player's own lines: a block like a speaker's, the character's name in
   the theme's gold beside their portrait (one custom property on #chat
   carries it, set by renderHeaderAvatar, so a long transcript never repeats
   the image), or their initials before one is painted; a gold bar down the
   left, the words in the warm white the player's own text has always had. */
.message.user{padding:8px 10px 10px 12px;border-left:2px solid var(--accent);border-radius:0 var(--ledger-radius,2px) var(--ledger-radius,2px) 0;background:var(--surface-low);color:var(--text-warm)}
.message.user .you-head{display:flex;align-items:center;gap:var(--space-4);margin:0 0 6px}
.you-face{display:grid;place-items:center;flex:none;width:28px;height:28px;overflow:hidden;border:1px solid var(--accent-600);border-radius:var(--ledger-radius,2px);background:var(--accent-950);color:var(--accent);font:600 var(--size-tiny)/1 var(--head)}
#chat.has-portrait .you-face{background:var(--player-avatar) 50% 20%/cover no-repeat var(--well);color:transparent}
.you-name{min-width:0;font:600 var(--size-label)/1.4 var(--head);letter-spacing:.08em;text-transform:uppercase;color:var(--accent);overflow-wrap:anywhere}
.message.user>p:not(.you-head){margin:0;color:var(--text-warm)}
.message.user>p:not(.you-head)+p{margin-top:.5em}

/* Spoken lines (src/ui/speech.mjs): each its own block, the speaker's name in
   capitals in their colour beside the manner, a bar of that colour down the
   left, the words upright in the body text's white. Someone met keeps their
   colour (by the order they were met); a name opens their sheet while they
   are here. No tone is gold: gold is the player's own lines. */
.speaker-line{--speaker:#e8a598;margin:1em 0;padding:2px 0 2px 14px;border-left:2px solid var(--speaker)}
.speaker-line[data-tone="2"]{--speaker:#9cc68f}
.speaker-line[data-tone="3"]{--speaker:#b8a2ff}
.speaker-line[data-tone="4"]{--speaker:#8ec3e6}
.speaker-line[data-tone="5"]{--speaker:#e59ac4}
.speaker-line[data-tone="6"]{--speaker:#7fcdbf}
.speaker-line.continued{margin-top:-1em;padding-top:.6em}
.message .speaker-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:2px 10px;margin:0 0 3px}
.speaker-name{font:600 var(--size-label)/1.4 var(--head);letter-spacing:.08em;text-transform:uppercase;color:var(--speaker)}
button.speaker-name{margin:-10px 0;padding:10px 0;border:0;border-radius:0;background:none;cursor:pointer;text-align:left}
button.speaker-name:hover,button.speaker-name:focus-visible{text-decoration:underline;text-underline-offset:3px}
.speaker-manner{font:400 var(--size-label)/1.4 var(--head);color:var(--muted)}
.message .speaker-words{margin:0;color:var(--text)}

/* Retry this turn (ui/retry-dialog.mjs): reason chips in two columns, the
   pressed ones in the theme's accent, and the instructions' count. */
.retry-card{width:min(520px,94vw)}
.retry-reasons{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-4)}
.retry-reasons button{min-height:40px;padding:8px 12px;border:1px solid var(--stone-800);border-radius:var(--radius-pill);background:var(--surface-raised);color:var(--text-soft);font:500 var(--size-ui)/1.25 var(--head)}
.retry-reasons button:hover,.retry-reasons button:focus-visible{border-color:var(--accent-600);color:var(--text)}
.retry-reasons button[aria-pressed=true]{border-color:var(--accent);background:var(--accent);color:var(--on-accent)}
.retry-text textarea{resize:vertical;min-height:96px}
.retry-count{align-self:flex-end;color:var(--muted);font:var(--size-caption) var(--head)}
.retry-narrator{margin:0}

/* Latest: floats over the bottom of the story once the reader has scrolled
   half a screen above the newest entry. */
.chat-frame{position:relative;flex:1;display:flex;flex-direction:column;min-height:0}
.chat-frame[hidden]{display:none}
.chat-frame>.chat{flex:1;min-height:0}
/* Round like Send and in line with it at the lower right: the chat bar's right
   padding (.composer in app.css) at each width. */
.jump-latest{position:absolute;right:max(15px,4vw,env(safe-area-inset-right));bottom:14px;z-index:4;display:grid;place-items:center;width:48px;height:48px;padding:0;border-color:var(--accent-600);border-radius:var(--radius-round);background:rgb(var(--surface-warm-rgb) / .95);color:var(--accent);box-shadow:var(--shadow-float)}
.jump-latest[hidden]{display:none}
.jump-latest-glyph{font-size:22px;transform:rotate(90deg)}
.jump-latest:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
@media(max-width:800px){.jump-latest{right:max(12px,env(safe-area-inset-right))}}
@media(max-width:480px){.jump-latest{right:max(10px,env(safe-area-inset-right))}}

/* Entry menu: one ⋯ button under each Voice entry (src/ui/entry-menu.mjs). */
.message-tools .entry-menu-button{border-color:transparent;color:var(--muted)}
.message-tools .entry-menu-button:hover,.message-tools .entry-menu-button:focus-visible{border-color:var(--line);color:var(--accent)}
.message-tools .entry-menu-button[aria-expanded=true]{border-color:var(--accent-600);color:var(--accent)}
.message-tools .entry-menu-button .action-glyph{width:18px;height:18px}
.entry-menu{position:fixed;z-index:30;display:flex;flex-direction:column;width:max-content;min-width:230px;max-width:calc(100vw - 16px);padding:6px;background:var(--surface);border:1px solid var(--accent-600);border-radius:var(--radius-xl);box-shadow:var(--shadow-pop)}
.entry-menu[hidden]{display:none}
.entry-menu [role=menuitem]{display:flex;align-items:center;gap:var(--space-6);width:100%;min-height:44px;padding:8px 12px 8px 10px;border:0;border-radius:var(--radius-md);background:none;color:var(--text);text-align:left;font:500 var(--size-ui) var(--head)}
.entry-menu [role=menuitem]:hover,.entry-menu [role=menuitem]:focus-visible{background:var(--accent-950);color:var(--accent);outline:none}
.entry-menu [role=menuitem]:disabled{opacity:.45;cursor:not-allowed;background:none;color:var(--text)}
.entry-menu .danger:hover,.entry-menu .danger:focus-visible{color:var(--danger)}
.entry-menu .action-glyph{width:17px;height:17px;flex:none;color:var(--accent-600)}
.entry-menu-label{display:grid;gap:1px;min-width:0}
.entry-menu-label small{max-width:260px;overflow:hidden;color:var(--muted);font:var(--size-caption) var(--head);text-overflow:ellipsis;white-space:nowrap}
.entry-menu-divider{height:1px;margin:4px 8px;background:var(--line)}

/* Edit & resend: the bar above the chat bar while the last action is being
   changed, and its warning once the last turn can no longer be replaced. */
.edit-bar{display:flex;align-items:center;gap:var(--space-5);padding:8px max(15px,4vw);border-top:1px solid var(--line);background:var(--surface-warm);color:var(--text-warm);font:var(--size-ui)/1.4 var(--head)}
.edit-bar>.action-glyph{width:16px;height:16px;flex:none;color:var(--accent)}
.edit-bar p{flex:1;min-width:0;margin:0}
.edit-bar button{flex:none;min-height:40px;padding:6px 12px;font:var(--size-label) var(--head)}
.edit-bar.lapsed{border-top-color:var(--danger-600);background:var(--danger-950);color:var(--danger-100)}
.edit-bar.lapsed>.action-glyph{color:var(--danger)}
@media(max-width:800px){.edit-bar{padding:8px 10px}}
@media(pointer:coarse){.edit-bar button{min-height:44px}}

/* Change dots: a tab whose records the last turn changed, until opened. */
.panel-tabs button,.mobile-nav button{position:relative}
.panel-tabs button[data-changed]::after,.mobile-nav button[data-changed]::after{content:"";position:absolute;top:11px;left:calc(50% + 10px);width:8px;height:8px;border-radius:var(--radius-round);background:var(--accent);box-shadow:0 0 0 2px var(--surface)}
.mobile-nav button[data-changed]::after{top:3px;left:calc(50% + 17px)}
.panel-tabs .tab-updated,.mobile-nav .tab-updated{position:absolute;width:1px;height:1px;margin:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
