/* Story-first observer. Keep the village's paper, forest green and book typography.
   UI layers: scene 1-8, toolbar 10, menu 11, native dialogs in the browser top layer.
   Shapes: controls 8px, dialogs 16px; the chronicle is a separate reading column. */
:root { --dim: #626f60; --reading: #fffdf7; --control: #edf1e6; --accent: #3f624e; }
#app { grid-template-columns: minmax(0, 1fr); grid-template-rows: 72px minmax(0, 1fr); }
button:focus-visible, a:focus-visible, summary:focus-visible, [tabindex]:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.scene-heading { top: 22px; left: 24px; max-width: calc(100% - 48px); }
.scene-heading > .eyebrow { display: none; }
.scene-heading h1 { font-size: clamp(23px, 2.3vw, 32px); }
.scene-heading p { font-size: 12px; }
/* Sound shares the zoom bar's square buttons and footer position. */
.scene-sounds { display: flex; align-items: center; border-right: 1px solid rgb(53 71 57 / .2); }
.view-tools .scene-sounds button { position: relative; display: inline-grid; place-items: center; padding: 0; border-radius: 0; color: inherit; }
.view-tools button:focus-visible { outline-offset: -3px; }
.sound-indicator { position: absolute; bottom: 4px; right: 4px; width: 4px; height: 4px; border-radius: 50%; background: #3f624e; }
.scene-sound-toggle[aria-pressed="false"] .sound-indicator { background: transparent; box-shadow: inset 0 0 0 1px #647362; }
#hud { position: static; background: transparent; border: 0; padding: 16px 0; color: var(--dim); font-size: 12px; }
.view-tools { bottom: 20px; }
#legend { bottom: 24px; max-width: calc(100% - 165px); }
.recording-playback { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; padding: 16px 0; border-top: 1px solid var(--line); }
.recording-playback[hidden] { display: none; }
.recording-playback #tickRange { flex: 1 1 120px; }
.recording-playback label { display: flex; align-items: center; gap: 6px; font-size: 12px; }
.recording-playback input[type=checkbox] { accent-color: var(--accent); }
/* These controls sit on a light scrim over the 3D scene in both interface themes. */
.view-tools { color: #354739; }
.view-tools button:hover { background: #dce4d4; }

/* The former floating story now owns the entire right-hand grid column. */
#bottom, .live-view #bottom { grid-area: side; position: relative; inset: auto; z-index: auto; width: auto; max-height: none; min-height: 0; margin: 0; padding: 28px 28px 0; border: 0; border-left: 1px solid var(--line); border-radius: 0; background: var(--reading); box-shadow: none; backdrop-filter: none; transition: none; }
.chron-heading { align-items: flex-start; gap: 12px; }
.chron-heading h2 { font-size: 30px; line-height: 1.15; margin-top: 6px; }
.chron-heading .eyebrow { color: var(--dim); font-size: 9px; letter-spacing: 1.6px; }
.chron-actions { padding-top: 2px; }
.chron-actions button { padding: 5px 0; border: 0; background: transparent; font-size: 11px; border-radius: 0; color: var(--dim); text-decoration: underline; text-underline-offset: 4px; }
.focus-mode #bottom { display: none; }

/* Native modal semantics provide focus containment and an inert background. */
.observer-dialog, #side.observer-dialog { position: fixed; inset: 0; width: min(620px, calc(100vw - 40px)); max-width: none; max-height: calc(100dvh - 64px); margin: auto; padding: 0; color: var(--text); background: var(--panel); border: 1px solid var(--line); border-radius: 16px; box-shadow: 0 24px 80px #1e352f38; overflow: hidden; }
.observer-dialog:not([open]), #side.observer-dialog:not([open]) { display: none; }
.observer-dialog[open], #side.observer-dialog[open] { display: flex; flex-direction: column; }
.observer-dialog::backdrop { background: #14251dcc; }
#side.village-dialog { width: min(980px, calc(100vw - 40px)); }
.dialog-heading { display: flex; flex-shrink: 0; align-items: center; justify-content: space-between; gap: 16px; padding: 22px 28px; border-bottom: 1px solid var(--line); }
.dialog-heading h2 { font-size: 28px; line-height: 1.2; }
.dialog-heading button { display: inline-flex; align-items: center; flex-shrink: 0; min-height: 40px; padding: 8px 14px; border-radius: 8px; font-size: 12px; }
.dialog-body { overflow-y: auto; overscroll-behavior: contain; padding: 24px 28px 28px; font-size: 14px; line-height: 1.7; }
.dialog-intro { color: var(--dim); margin-bottom: 22px; }
.dialog-body .card { margin: 0; padding: 20px 0; }
.dialog-body .card:first-child { border-top: 0; padding-top: 0; }
.dialog-body .card h3, .dialog-body summary { font-size: 12px; color: var(--text); }
.dialog-body .quiet-button { display: inline-flex; }
#agentDetail { scroll-margin: 16px; }
.dialog-body .agent-chip, .dialog-body .pet-row { background: var(--paper); border-color: var(--line); padding: 11px 12px; }
.dialog-body .agent-chip.sel { background: var(--control); border-color: var(--accent); }
.dialog-body .agent-row-head strong, .dialog-body .pet-row strong { color: var(--text); font-size: 13px; }
.dialog-body .agent-row-head small, .dialog-body .agent-traits, .dialog-body .pet-row p, .dialog-body .pet-row small { color: var(--dim); font-size: 11px; }
.dialog-body .agent-status, .dialog-body .pet-status { color: var(--accent); font-size: 12px; }
.dialog-body .kv { font-size: 12px; }
.village-surroundings, .recording-details { border-top: 1px solid var(--line); margin-top: 18px; }
.village-surroundings > summary, .recording-details > summary { cursor: pointer; padding: 18px 0; font-weight: 600; }
.village-surroundings-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 28px; }
.dialog-body .music-state { margin-top: 12px; }
.dialog-body .music-action { font-size: 12px; padding: 10px 14px; border-radius: 8px; color: var(--text); border-color: var(--line); background: var(--control); }
.dialog-body .music-credit { color: var(--dim); font-size: 12px; }
.dialog-body .credit-track { color: var(--text); font-size: 14px; }
.dialog-body .credit-license, .dialog-body #musicStatus, .dialog-body #ambienceStatus, .dialog-body .ambience-note { font-size: 12px; color: var(--dim); }
.dialog-body a { color: var(--accent); }
.dialog-body .run-control { border: 0; padding: 0 0 20px; }
.dialog-body .run-control select { max-width: 100%; }
#aboutContent p + p { margin-top: 16px; }
#aboutContent .seo-about { border: 0; padding: 0; }
#aboutContent .seo-about h2 { color: var(--text); font-size: 25px; }
#aboutContent .seo-about p, #aboutContent .seo-about li { color: var(--dim); font-size: 14px; }
#aboutContent .seo-about a { color: var(--accent); }
.about-author { margin-top: 24px; padding-top: 20px; border-top: 1px solid var(--line); }
.about-author h3 { color: var(--text); font-size: 17px; margin: 0 0 10px; }
.about-author p { color: var(--dim); font-size: 14px; line-height: 1.6; }
.about-author p + p { margin-top: 12px; }

@media (max-width: 1100px) {
  #bottom { padding-left: 22px; padding-right: 22px; }
  .chron-heading h2 { font-size: 27px; }
}
@media (max-width: 1000px) {
  body { overflow: auto; }
  #app { height: auto; min-height: 100dvh; overflow: visible; grid-template-columns: minmax(0, 1fr); grid-template-rows: 96px 52dvh auto; grid-template-areas: 'top' 'view' 'side'; }
  #view { min-height: 300px; }
  .scene-heading { left: 18px; top: 15px; }
  .scene-heading h1 { font-size: 23px; }
  .scene-heading p { font-size: 11px; }
  #legend { left: 18px; bottom: 24px; max-width: calc(100% - 148px); font-size: 10px; }
  .live-view #legend { max-width: calc(100% - 148px); }
  .view-tools { right: 14px; bottom: 20px; }
  .view-tools button { width: 36px; height: 36px; }
  #bottom, .live-view #bottom { width: auto; max-height: none; min-height: 360px; padding: 26px 22px 0; border-left: 0; border-top: 1px solid var(--line); }
  .chron-heading h2 { font-size: 29px; }
  .observer-dialog, #side.village-dialog { width: calc(100vw - 24px); max-height: calc(100dvh - 32px); }
  .dialog-heading { padding: 18px 20px; }
  .dialog-heading h2 { font-size: 25px; }
  .dialog-body { padding: 20px; }
  .village-surroundings-grid { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .dialog-body .agent-portrait { width: 32px; height: 32px; }
}
@media (prefers-color-scheme: dark) {
  :root { --paper: #202c26; --panel: #26332b; --panel-2: #2c3b31; --reading: #222f27; --text: #e3e9dc; --dim: #b2bdac; --line: #445447; --control: #344a39; --accent: #b2d1ac; }
  .observer-dialog .card h3, .observer-dialog .metrics b, .observer-dialog .summary summary { color: var(--text); }
  .observer-dialog .music-action { color: var(--text); background: var(--control); }
  .observer-dialog .music-credit a { color: var(--accent); }
  .observer-dialog hr { border-color: var(--line); }
  .observer-dialog .badge { color: var(--accent); }
  .observer-dialog .bar .name, .observer-dialog .meter { color: var(--dim); }
  .observer-dialog .track { background: var(--line); }
  .observer-dialog .weather-card, .observer-dialog .event-card { background: var(--paper); border-color: var(--line) !important; }
  .observer-dialog .weather-card p, .observer-dialog #weatherDetail, .observer-dialog .event-card > p { color: var(--dim); }
  .observer-dialog #buildingList button, .observer-dialog .season-track span { background: var(--control); color: var(--text); border-color: var(--line); }
  button:hover, .seo-header-link:hover { background: var(--control); }
  select { color-scheme: dark; }
}
@media (prefers-reduced-motion: reduce) {
  button, .observer-dialog, #bottom { transition: none; }
}

/* Header. One floating bar at every width, one row, and source order = visual order = tab order.
   961px and up: brand, text nav (Story, Village, About, More), then Hide panels and Pomodoro with icons.
   960px and down: the same six controls as icon buttons; the labels stay in the DOM (font-size 0) and as title tooltips.
   600px and down: the wordmark folds to its mark; 360px and down: the mark goes.
   Hierarchy: nav is ghost, Hide panels is outlined, Pomodoro is the one filled control. Only Pomodoro hides the bar. */
:root { --toolbar-top: max(12px, env(safe-area-inset-top)); --toolbar-h: 64px; --toolbar-height: calc(var(--toolbar-top) + var(--toolbar-h)); }
#top {
  --text: #1d3a29; --dim: #2f4a39; --accent: #2a4f38; --accent-ink: #f6faf1; --control: rgb(42 79 56 / .09); --edge: rgb(42 79 56 / .28);
  --ease: cubic-bezier(.25, 1, .5, 1);
  --icon-story: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2 5h7a3 3 0 0 1 3 3v12a2 2 0 0 0-2-2H2zM22 5h-7a3 3 0 0 0-3 3v12a2 2 0 0 1 2-2h8z'/%3E%3C/svg%3E");
  --icon-village: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 21V11l5-4 5 4v10M13 21v-7l4-3 4 3v7M2 21h20M7 21v-5h2v5'/%3E%3C/svg%3E");
  --icon-about: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 11v5M12 8h.01'/%3E%3C/svg%3E");
  --icon-more: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'%3E%3Ccircle cx='5' cy='12' r='1.8'/%3E%3Ccircle cx='12' cy='12' r='1.8'/%3E%3Ccircle cx='19' cy='12' r='1.8'/%3E%3C/svg%3E");
  --icon-pomodoro: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='13' r='8'/%3E%3Cpath d='M12 9v4l3 2M9 2h6'/%3E%3C/svg%3E");
  --icon-expand: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7'/%3E%3C/svg%3E");
  --icon-collapse: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 10h-6V4M4 14h6v6M14 10l7-7M3 21l7-7'/%3E%3C/svg%3E");
  --icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  position: fixed; top: var(--toolbar-top); left: max(16px, env(safe-area-inset-left)); right: max(16px, env(safe-area-inset-right));
  z-index: 10; display: flex; align-items: center; gap: 8px;
  height: var(--toolbar-h); min-height: var(--toolbar-h); padding: 0 12px 0 16px;
  color: var(--text); background: rgb(246 250 240 / .86);
  border: 1px solid rgb(255 255 255 / .75); border-radius: 18px;
  box-shadow: 0 10px 30px rgb(27 47 33 / .14), 0 1px 3px rgb(27 47 33 / .1);
  backdrop-filter: blur(20px) saturate(140%); -webkit-backdrop-filter: blur(20px) saturate(140%);
  transition: opacity 180ms ease, transform 180ms ease;
}
#top .brand { flex: 0 0 auto; }
#top .brand-logo { display: block; width: 216px; height: 50px; object-fit: cover; }
#top .live-note { display: none; }
#top .spacer { display: block; flex: 1 1 8px; }
#top .observer-nav, #top .primary-actions { display: flex; align-items: center; gap: 2px; }
/* A short rule sets the two actions apart from the navigation. */
#top .primary-actions { gap: 8px; }
#top .primary-actions::before { content: ''; width: 1px; height: 24px; margin-right: 6px; background: rgb(42 79 56 / .18); }

#top .quiet-button {
  --h: 40px;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: var(--h); padding: 0 14px; border: 1px solid transparent; border-radius: 10px;
  background: transparent; color: var(--text); cursor: pointer;
  font-family: inherit; font-size: 13px; font-weight: 600; line-height: 1; letter-spacing: .005em; text-decoration: none; white-space: nowrap;
  transition: background-color 150ms var(--ease), border-color 150ms var(--ease), color 150ms var(--ease), transform 150ms var(--ease);
}
/* The daily saga's links (specs/021) show only while the saga is on. The button display above beats the
   user-agent [hidden] rule, so hidden must be said again here, or every visitor sees a link to a 404. */
#top [data-saga-link][hidden] { display: none; }
#top .quiet-button:hover, #top .tools-menu[open] > summary { background: var(--control); }
#top .quiet-button:active { transform: translateY(1px); }
#top :is(button, a, summary):focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Outlined: the panels toggle. Its label already says which way it goes; it stays lit while the panels are away. */
#top #focusBtn { border-color: var(--edge); }
.focus-mode #top #focusBtn { background: var(--control); }
/* Filled: the one primary action. */
#top #pomodoroBtn { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
#top #pomodoroBtn:hover { background: #22412e; border-color: #22412e; }

/* Icons: masks in currentColor. The actions always carry one; the nav gains them when the labels go. */
#top .primary-actions .quiet-button::before, #top .observer-nav > :is(button, a)::before, #top .tools-menu > summary::before {
  content: ''; flex: 0 0 auto; width: 18px; height: 18px; background: currentColor;
  -webkit-mask: var(--icon) center / contain no-repeat; mask: var(--icon) center / contain no-repeat;
}
#top .observer-nav > :is(button, a)::before, #top .tools-menu > summary::before { content: none; }
#top .observer-nav > [data-saga-link] { --icon: var(--icon-story); }
#top .observer-nav > [data-dialog="side"] { --icon: var(--icon-village); }
#top #aboutMenu > summary { --icon: var(--icon-about); }
#top #toolsMenu > summary { --icon: var(--icon-more); }
#top #pomodoroBtn { --icon: var(--icon-pomodoro); }
#top #focusBtn { --icon: var(--icon-expand); }
.focus-mode #top #focusBtn { --icon: var(--icon-collapse); }

/* Menus. */
.tools-menu { position: relative; }
.tools-menu > summary { cursor: pointer; list-style: none; gap: 6px; }
.tools-menu > summary::-webkit-details-marker { display: none; }
#top .tools-menu > summary::after {
  content: ''; width: 14px; height: 14px; margin-right: -3px; background: currentColor; opacity: .65;
  -webkit-mask: var(--icon-chevron) center / contain no-repeat; mask: var(--icon-chevron) center / contain no-repeat;
  transition: transform 150ms var(--ease);
}
#top .tools-menu[open] > summary::after { transform: rotate(180deg); }
.tools-menu-content {
  position: absolute; right: 0; top: calc(100% + 12px); z-index: 11; width: 224px; padding: 6px;
  background: rgb(250 252 246); border: 1px solid rgb(42 79 56 / .16); border-radius: 14px;
  box-shadow: 0 16px 40px rgb(27 47 33 / .18), 0 2px 6px rgb(27 47 33 / .08);
  animation: menu-in 160ms var(--ease);
}
@keyframes menu-in { from { opacity: 0; transform: translateY(-4px); } }
#top .tools-menu-content .quiet-button, #top .tools-menu-content .seo-header-link {
  display: flex; width: 100%; justify-content: flex-start; margin: 0; padding: 0 12px; border: 0; border-radius: 8px;
  color: var(--text); font-size: 13px; font-weight: 500; text-align: left;
}
#top #aboutMenu [data-dialog] { position: relative; margin-bottom: 7px; }
#top #aboutMenu [data-dialog]::after { content: ''; position: absolute; left: 12px; right: 12px; bottom: -4px; height: 1px; background: rgb(42 79 56 / .14); }

/* Narrower than a laptop: a little tighter, so the labelled bar still fits one row above 960px. */
@media (max-width: 1180px) {
  #top .brand-logo { width: 190px; height: 44px; }
  #top .quiet-button { padding: 0 12px; }
}
/* The saga link is the header's only story entry and always there, so down to the icon bar the labelled row is
   tighter still: at 961px it measured about 65px too wide for the 190px mark and 12px button padding (Chromium); the unread count
   then sits on the button's corner instead of widening it. */
@media (max-width: 1060px) {
  #top .brand-logo { width: 150px; height: 35px; }
  #top .quiet-button { padding: 0 8px; }
}
/* Tablets and phones: seven icon buttons in a 56px bar; the label stays for screen readers and as the tooltip. */
@media (max-width: 960px) {
  :root { --toolbar-top: max(8px, env(safe-area-inset-top)); --toolbar-h: 56px; }
  #top { left: 8px; right: 8px; gap: 4px; padding: 0 6px 0 10px; border-radius: 16px; }
  #top .brand-logo { width: 174px; height: 40px; }
  #top .quiet-button { --h: 44px; }
  #top .primary-actions { gap: 2px; }
  #top .primary-actions::before { content: none; }
  #top .observer-nav > :is(button, a), #top .tools-menu > summary, #top .primary-actions .quiet-button { flex: 0 0 44px; width: 44px; padding: 0; gap: 0; font-size: 0; }
  #top .primary-actions .quiet-button::before, #top .observer-nav > :is(button, a)::before, #top .tools-menu > summary::before { content: ''; width: 20px; height: 20px; }
  #top .tools-menu > summary::after { content: none; }
  /* Both menus hang from the bar's right edge, whichever icon opened them. */
  #top .tools-menu { position: static; }
  #top .tools-menu-content { width: min(240px, calc(100vw - 32px)); }
  #top .tools-menu-content .quiet-button { --h: 44px; }
}
@media (max-width: 600px) {
  #top { padding: 0 6px 0 8px; }
  #top .brand-logo { width: 40px; height: 40px; object-position: left center; }
  /* Seven 44px icons, the mark and the gaps need about 410px; a phone is often 360-393px.
     Each icon gives up a few pixels instead of the last one (Pomodoro) running off the edge. */
  #top .spacer { flex-basis: 0; }
  #top .observer-nav, #top .primary-actions { min-width: 0; }
  #top .observer-nav > :is(button, a), #top .observer-nav > .tools-menu, #top .primary-actions .quiet-button { flex: 0 1 44px; width: 44px; min-width: 34px; }
  #top .tools-menu > summary { width: 100%; }
}
@media (max-width: 360px) {
  #top .brand { display: none; }
  #top { padding: 0 6px; }
}
@media (pointer: coarse) {
  #top .quiet-button { --h: 44px; }
}
@supports not (backdrop-filter: blur(1px)) {
  #top { background: #f1f5ea; }
}
@media (prefers-reduced-transparency: reduce) {
  #top { background: #f1f5ea; backdrop-filter: none; -webkit-backdrop-filter: none; }
}
@media (prefers-reduced-motion: reduce) {
  #top, #top .quiet-button, #top .tools-menu > summary::after { transition: none; }
  .tools-menu-content { animation: none; }
}
#app { grid-template-rows: minmax(0, 1fr); grid-template-areas: 'view'; }
#revealControls { display: none; }
.scene-heading { top: calc(var(--toolbar-height) + 24px); }
.interior-top { top: calc(var(--toolbar-height) + 24px); }
#interiorFloors { top: calc(var(--toolbar-height) + 104px); }
/* The village toolbar and chronicle are siblings, never overlapping surfaces. */
#bottom, .live-view #bottom {
  margin: 0; padding: 32px 28px 0;
  border: 0; border-left: 1px solid var(--line); border-radius: 0; overflow: hidden;
}
.chron-heading h2 { margin-top: 0; }
body.focus-mode { overflow: hidden; }
.focus-mode #app { height: 100dvh; min-height: 0; grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); grid-template-areas: 'view'; }
.focus-mode #view { min-height: 0; outline: none; }
.focus-mode .scene-heading, .focus-mode #legend, .focus-mode .view-tools,
.focus-mode .nm-label, .focus-mode .place-label, .focus-mode .building-label,
.focus-mode .sleep-label, .focus-mode .bubble:not(.signal):not(.has-icon), .focus-mode #interiorPanel { visibility: hidden; pointer-events: none; }
/* Village reactions (specs/015): immersive mode keeps emotes and needs, and thoughts as their icon only. */
.focus-mode .bubble.has-icon > div { display: none; }
.focus-mode .bubble.has-icon { padding: 3px; border-radius: 50%; }
.pomodoro-focus #top { transform: translateY(calc(-100% - 24px)); opacity: 0; visibility: hidden; pointer-events: none; }
.focus-mode #pomodoroToasts { top: max(20px, env(safe-area-inset-top)); }
body:not(.focus-mode) #pomodoroTimer { bottom: 64px; }
.pomodoro-legal { display: none; }
.pomodoro-focus .pomodoro-legal { display: flex; position: fixed; bottom: 10px; right: 14px; z-index: 10; gap: 12px; padding: 4px 8px; border-radius: 8px; background: rgb(245 250 239 / .7); backdrop-filter: blur(12px); font: 10px/1.5 system-ui,sans-serif; }
.pomodoro-legal a, .pomodoro-legal button { color: #203d2b; font: inherit; border: 0; background: none; padding: 0; text-decoration: underline; cursor: pointer; }
@media (max-width: 1000px) {
  #app { grid-template-rows: max(420px, 65dvh) auto; grid-template-areas: 'view' 'side'; }
  #bottom, .live-view #bottom { margin: 0; padding: 28px 22px 0; border-left: 0; border-top: 1px solid var(--line); overflow: visible; }
  .scene-heading { top: calc(var(--toolbar-height) + 12px); }
}

/* The live feed floats over the scene; feathered shade keeps text readable in daylight. */
#chatPanel {
  position: absolute; z-index: 3; right: 16px; bottom: 72px;
  display: flex; flex-direction: column; width: clamp(320px, 28vw, 400px);
  height: min(52%, 440px); max-height: calc(100% - var(--toolbar-height) - 180px); min-height: 0;
  color: #fff; background: transparent; border: 0; border-radius: 0; box-shadow: none;
  font: 12px/1.5 'DM Sans', sans-serif; text-shadow: 0 1px 3px #15231d, 0 0 8px rgb(10 23 16 / .75);
  pointer-events: none;
}
#chatPanel::before { content: ''; position: absolute; inset: -24px -28px -20px -24px; z-index: -1; background: radial-gradient(ellipse closest-side at 50% 50%, rgb(8 22 15 / .58), rgb(8 22 15 / .3) 60%, transparent 100%); pointer-events: none; }
#chatPanel[hidden], .focus-mode #chatPanel, .interior-open #chatPanel { display: none; }
#chatPanel.is-collapsed { width: auto; height: auto; max-width: calc(100% - 32px); }
#chatPanel button, #chatPanel .chat-log { pointer-events: auto; }
#chatPanel button:focus-visible, #chatPanel .chat-log:focus-visible { outline: 2px solid #fff3c5; outline-offset: -2px; }
.chat-heading { flex: 0 0 auto; margin: 0; font: inherit; }
.chat-toggle { display: flex; align-items: center; gap: 8px; width: 100%; min-height: 44px; padding: 8px 12px; border: 0; border-radius: 0; background: transparent; color: inherit; text-shadow: inherit; text-align: left; font: 600 12px/1.3 'DM Sans', sans-serif; }
.chat-toggle:hover { background: transparent; color: #fff3c5; }
.chat-toggle-icon { font-size: 14px; }
.chat-toggle-label { font-size: 12px; letter-spacing: .03em; white-space: nowrap; }
.chat-count { color: #fff3c5; white-space: nowrap; }
.chat-chevron { flex: 0 0 auto; width: 7px; height: 7px; margin-left: auto; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: translateY(-2px) rotate(45deg); }
.is-collapsed .chat-chevron { transform: translateY(2px) rotate(-135deg); margin-left: 6px; }
.chat-body { position: relative; display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.chat-body[hidden] { display: none; }
.chat-avatars { display: flex; flex-direction: column; align-items: flex-start; padding-top: 2px; }
.chat-avatar { position: relative; display: grid; place-items: center; flex: 0 0 auto; width: 32px; height: 32px; border-radius: 50%; overflow: hidden; box-shadow: 0 0 0 1px rgb(255 255 255 / .55); font-weight: 600; }
.chat-portrait { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; background-color: inherit; }
.chat-avatars.is-group .chat-avatar { width: 24px; height: 24px; }
.chat-avatars.is-group .chat-avatar + .chat-avatar { margin-top: -6px; }
.chat-avatars.is-group .chat-avatar:nth-child(even) { margin-left: 10px; }
.chat-status { padding: 12px; color: #f0f3eb; font-size: 12px; }
.chat-status[hidden] { display: none; }
.chat-status p { margin: 0; }
.chat-log { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; touch-action: pan-y; padding: 8px 0; scrollbar-width: thin; scrollbar-color: rgb(255 255 255 / .25) transparent; mask-image: linear-gradient(transparent, #000 14px, #000); }
.chat-list { list-style: none; margin: 0; padding: 0; }
.chat-entry { display: grid; grid-template-columns: 34px minmax(0, 1fr); gap: 8px; padding: 8px 12px; }
.chat-icon { font-size: 13px; line-height: 20px; text-align: center; }
.chat-meta { display: flex; align-items: center; gap: 8px; margin: 0; min-width: 0; color: #e8ede5; font-size: 11px; }
.chat-who { display: inline-flex; align-items: center; gap: 4px; min-width: 0; }
.chat-who b { overflow: hidden; color: #fff; font-weight: 700; text-overflow: ellipsis; white-space: nowrap; }
.chat-time { margin-left: auto; font-size: 10px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.chat-text { margin: 2px 0 0; color: #fff; font-size: 13px; line-height: 1.5; overflow-wrap: anywhere; }
.chat-thought .chat-text, .chat-speech.chat-unquoted .chat-text { font-style: italic; }
/* Villager voices (specs/009): the thought under an action, and one conversation as one exchange. */
.chat-thought-line { margin: 3px 0 0; color: #eef3ea; font-size: 13px; font-style: italic; line-height: 1.45; overflow-wrap: anywhere; }
.chat-entry.chat-thread-cont { padding-top: 0; }
.chat-entry.chat-thread-cont .chat-avatars { visibility: hidden; }
.chat-entry.chat-thread-cont .chat-who { display: none; }
.chat-title { margin: 2px 0 0; color: #fff3c5; font-size: 13px; font-weight: 700; line-height: 1.4; }
.chat-narrator .chat-text { font-family: Georgia, serif; }
.chat-read { margin-top: 4px; padding: 4px 0; border: 0; border-radius: 0; background: none; color: #fff3c5; text-shadow: inherit; font-size: 11px; text-decoration: underline; text-underline-offset: 3px; }
.chat-read:hover { background: none; text-decoration-thickness: 2px; }
.chat-notes { display: flex; flex-wrap: wrap; gap: 6px; margin: 3px 0 0; color: #e8ede5; font-size: 10px; }
.chat-habit { font-style: italic; }
.chat-notes > span + span::before { content: '· '; }
.chat-new { position: absolute; left: 50%; bottom: 10px; z-index: 1; transform: translateX(-50%); padding: 7px 12px; border: 1px solid rgb(255 255 255 / .3); border-radius: 999px; background: rgb(22 40 29 / .9); color: #fff; font-size: 11px; font-weight: 600; }
.chat-new:hover { background: #253d2e; }
.chat-new:active { transform: translateX(-50%) translateY(1px); }
.chat-new[hidden] { display: none; }
.chat-sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
.chat-entry-new { animation: chat-in .28s ease-out; }
@keyframes chat-in { from { opacity: 0; transform: translateY(6px); } }
@media (prefers-reduced-motion: reduce) { .chat-entry-new { animation: none; } }
/* On narrow screens the feed starts folded and opens over the lower scene. */
@media (max-width: 900px) {
  #chatPanel { left: 8px; right: 8px; bottom: calc(8px + env(safe-area-inset-bottom)); width: auto; height: min(45%, 360px); max-height: calc(100% - var(--toolbar-height) - 150px); }
  #chatPanel.is-collapsed { left: auto; bottom: calc(72px + env(safe-area-inset-bottom)); height: auto; max-width: calc(100% - 16px); }
  #view:has(> #chatPanel:not([hidden])) #legend { bottom: 24px; }
  #view:has(> #chatPanel:not([hidden]):not(.is-collapsed)) #legend { display: none; }
  #view:has(> #chatPanel:not([hidden]):not(.is-collapsed)) .view-tools { bottom: calc(min(45%, 360px) + 16px); }
}

/* The village uses the whole viewport at every width. */
#app, .focus-mode #app { height: 100dvh; min-height: 420px; grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); grid-template-areas: 'view'; }

/* Leave room for the combined six-button footer bar. */
#legend, .live-view #legend { max-width: calc(100% - 280px); }
@media (max-width: 600px) { #legend { display: none; } }

/* Phones. The header is one 56px row: brand mark, then six icon buttons (Story, Village, Pomodoro, panels,
   About, More). Labels stay in the DOM (font-size 0) so screen readers keep the names; icons are masks in
   currentColor. Labels in the scene stay readable, and dialogs slide up as sheets. Nothing here changes
   markup order or what a control does. */
@media (max-width: 600px) {
  .scene-heading h1 { font-size: 22px; text-wrap: balance; }

  /* Zoom and sound bar: full-size touch targets, clear of the home indicator. */
  .view-tools { right: 10px; bottom: calc(14px + env(safe-area-inset-bottom)); }
  .view-tools button { width: 44px; height: 44px; }
  #chatPanel.is-collapsed { bottom: calc(66px + env(safe-area-inset-bottom)); }
  /* With the feed open the bar folds into two short columns on the right edge instead of covering the village. */
  #view:has(> #chatPanel:not([hidden]):not(.is-collapsed)) .view-tools { display: grid; grid-auto-flow: column; grid-template-rows: repeat(3, 44px); grid-template-columns: 44px 44px; }
  #view:has(> #chatPanel:not([hidden]):not(.is-collapsed)) .scene-sounds { display: contents; }
  #view:has(> #chatPanel:not([hidden]):not(.is-collapsed)) .view-tools :is(#zoomOut, #resetView, #zoomIn) { border-left: 1px solid rgb(53 71 57 / .2); }
  .chat-text, .chat-thought-line { font-size: 14px; }
  .chat-notes { font-size: 11px; }
  .chat-read { min-height: 44px; display: inline-flex; align-items: center; }

  /* Pomodoro: 44px tools, and the legal links get their own line under the pill. */
  #pomodoroTimer, body:not(.focus-mode) #pomodoroTimer { bottom: calc(52px + env(safe-area-inset-bottom)); max-width: calc(100vw - 16px); }
  .pomodoro-tools button { min-width: 44px; min-height: 44px; }
  .pomodoro-focus .pomodoro-legal { left: 8px; right: 8px; bottom: calc(8px + env(safe-area-inset-bottom)); justify-content: center; font-size: 12px; }
  .pomodoro-legal a, .pomodoro-legal button { min-height: 32px; display: inline-flex; align-items: center; }

  /* Inside a house. */
  #leaveInterior { min-height: 44px; font-size: 13px; }
  #interiorFloors button { min-height: 44px; font-size: 12px; padding: 0 12px; }
  .interior-note { font-size: 11px; }
  .interior-bottom { bottom: calc(76px + env(safe-area-inset-bottom)); max-height: min(30dvh, 240px); }

  /* Dialogs: bottom sheets. */
  .observer-dialog, #side.observer-dialog, #side.village-dialog { inset: auto 0 0 0; width: 100vw; max-width: 100vw; max-height: 92dvh; margin: 0; border-width: 1px 0 0; border-radius: 20px 20px 0 0; animation: sheet-up .22s ease-out; }
  .dialog-heading { padding: 14px 16px 14px 20px; }
  .dialog-heading h2 { font-size: 22px; }
  .dialog-heading button { min-height: 44px; min-width: 44px; }
  .dialog-body { padding: 16px 20px calc(24px + env(safe-area-inset-bottom)); }
  .dialog-body .music-action { min-height: 44px; }
  .village-surroundings > summary, .recording-details > summary { min-height: 44px; display: flex; align-items: center; padding: 0; }
  .dialog-body .agent-chip, .dialog-body .pet-row { padding: 12px; }
}
@media (max-width: 600px), (max-height: 500px) and (orientation: landscape) {
  /* Labels in the scene: names at 11px, the occupant count as a badge instead of "N inside ↗". */
  .building-label { font-size: 11px; letter-spacing: .2px; padding: 5px 8px; min-height: 28px; display: inline-flex; align-items: center; gap: 5px; }
  .building-label .bl-status { display: none; }
  .building-label:not([data-count="0"])::after { content: attr(data-count); display: inline-grid; place-items: center; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px; background: #f3dfa0; color: #33452f; font-size: 10px; line-height: 1; }
  .nm-label { font-size: 11px; padding: 3px 7px; }
  .bubble { font-size: 11px; max-width: 150px; }
}
@keyframes sheet-up { from { opacity: 0; transform: translateY(28px); } }
@media (max-width: 600px) and (prefers-reduced-motion: reduce) {
  .observer-dialog, #side.observer-dialog { animation: none; }
}

/* Landscape phones: the scene keeps its height (no page scroll) and the header is one row. */
@media (max-width: 1000px) and (max-height: 500px) and (orientation: landscape) {
  #app, .focus-mode #app { min-height: 0; }
  .scene-heading { display: none; }
  .observer-dialog, #side.observer-dialog, #side.village-dialog { max-height: calc(100dvh - 16px); }
  #chatPanel { left: auto; right: 8px; width: min(48vw, 360px); height: min(60%, 240px); max-height: calc(100% - var(--toolbar-height) - 80px); }
  #chatPanel.is-collapsed { bottom: 68px; }
  .view-tools { bottom: 12px; }
  .view-tools button { width: 40px; height: 40px; }
  #view:has(> #chatPanel:not([hidden]):not(.is-collapsed)) .view-tools { bottom: 12px; right: calc(min(48vw, 360px) + 20px); }
}

/* The room's backdrop turns navy at night; its title and eyebrow sit straight on it. */
#interiorPanel.is-night .interior-top h2 { color: #f6f1de; }
#interiorPanel.is-night .interior-top .eyebrow { color: #c4d0c0; }

/* Life in the village: the six neighbours in one row, then the chosen one across the full width.
   The model stays in view beside the reading column; the tabs keep "now", story and ways apart. */
.village-roll { margin: 0 0 26px; }
.village-roll .agents { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 10px; }
.village-roll .agent-chip { display: flex; flex-direction: column; align-items: center; gap: 1px; min-width: 0; padding: 14px 8px 12px; text-align: center; line-height: 1.35; background: var(--paper); border: 1px solid var(--line); border-radius: 12px; transition: border-color .2s, background-color .2s, transform .3s cubic-bezier(.25, 1, .5, 1); }
.village-roll .agent-chip:hover { background: var(--paper); border-color: color-mix(in srgb, var(--accent) 45%, var(--line)); transform: translateY(-2px); }
.village-roll .agent-chip.sel { background: var(--control); border-color: var(--accent); }
.village-roll .agent-portrait { width: 56px; height: 56px; margin-bottom: 7px; background-color: var(--villager-tint); border: 2px solid var(--panel); box-shadow: 0 0 0 1px var(--line); transition: box-shadow .2s; }
.village-roll .agent-chip.sel .agent-portrait { box-shadow: 0 0 0 2px var(--accent); }
.village-roll .agent-name { font-size: 14px; color: var(--text); }
.village-roll .agent-role { font-size: 11px; color: var(--dim); }
.village-roll .agent-status { display: flex; flex-direction: column; margin-top: 7px; font-size: 11px; line-height: 1.35; overflow-wrap: anywhere; }
.village-roll .agent-doing { color: var(--accent); font-weight: 600; }
.village-roll .agent-where { color: var(--dim); }
.village-roll .agent-where:empty { display: none; }

.profile { display: grid; grid-template-columns: 216px minmax(0, 1fr); gap: 36px; align-items: start; animation: profile-in .36s cubic-bezier(.25, 1, .5, 1); }
.profile-figure { position: sticky; top: 0; display: flex; flex-direction: column; gap: 16px; }
/* The villager turns in a little lit room of their own colour. */
.villager-viewer { position: relative; width: 168px; height: 236px; border: 1px solid var(--line); border-radius: 12px; overflow: hidden; background: radial-gradient(ellipse at 50% 78%, color-mix(in srgb, var(--villager-tint, #dce4d4) 46%, var(--paper)) 0%, color-mix(in srgb, var(--villager-tint, #dce4d4) 14%, var(--paper)) 72%); cursor: grab; touch-action: pan-y; }
.villager-viewer.grabbed { cursor: grabbing; }
.villager-viewer canvas { display: block; width: 100%; height: 100%; outline-offset: -3px; }
.villager-viewer-hint { position: absolute; left: 0; right: 0; bottom: 6px; text-align: center; font-size: 10px; letter-spacing: .06em; color: var(--dim); pointer-events: none; opacity: 0; transition: opacity .2s; }
.villager-viewer:hover .villager-viewer-hint, .villager-viewer:focus-within .villager-viewer-hint { opacity: 1; }
.villager-viewer.grabbed .villager-viewer-hint { opacity: 0; }
.profile-figure .villager-viewer { width: 100%; height: 288px; }
.profile-label { display: block; margin: 0 0 6px; font-size: 10px; font-weight: 700; letter-spacing: 1.4px; text-transform: uppercase; color: var(--dim); }
.profile-status { padding: 0 2px; line-height: 1.45; }
.profile-doing { font-size: 15px; font-weight: 600; color: var(--accent); }
.profile-where { font-size: 13px; color: var(--text); }
.profile-wakes { margin-top: 4px; font-size: 12px; color: var(--dim); }
.profile-quiet { font-size: 13px; color: var(--dim); }

.profile-head { padding-bottom: 20px; }
.profile-kicker { font-size: 11px; font-weight: 700; letter-spacing: 1.6px; text-transform: uppercase; color: var(--dim); }
.profile-name { margin: 4px 0 10px; font: 400 42px/1.05 'DM Serif Display', Georgia, serif; letter-spacing: 0; text-transform: none; color: var(--text); }
.profile-quote { max-width: 56ch; font: italic 17px/1.55 Georgia, serif; color: var(--text); text-wrap: pretty; }
.profile-note { display: inline-flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; margin-top: 14px; padding: 0; text-align: left; font-size: 13px; line-height: 1.5; color: var(--dim); background: transparent; border: 0; }
.profile-note::before { content: '❦'; color: var(--stamp, var(--gold)); }
.profile-note:hover { background: transparent; color: var(--text); }
.profile-note-more { font-size: 11px; color: var(--accent); white-space: nowrap; opacity: 0; transition: opacity .2s; }
.profile-note:hover .profile-note-more, .profile-note:focus-visible .profile-note-more { opacity: 1; }
@media (hover: none) { .profile-note-more { opacity: .8; } }
.profile-note-text.is-new { animation: note-in .45s cubic-bezier(.22, 1, .36, 1); }
.visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

.profile-tabs { display: flex; gap: 26px; margin-bottom: 24px; border-bottom: 1px solid var(--line); }
.profile-tabs [role=tab] { position: relative; padding: 10px 0 12px; font-size: 13px; font-weight: 600; color: var(--dim); background: transparent; border: 0; border-radius: 0; }
.profile-tabs [role=tab]:hover { background: transparent; color: var(--text); }
.profile-tabs [role=tab][aria-selected=true] { color: var(--text); }
.profile-tabs [role=tab]::after { content: ''; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; background: var(--accent); transform: scaleX(0); transform-origin: left; transition: transform .3s cubic-bezier(.25, 1, .5, 1); }
.profile-tabs [role=tab][aria-selected=true]::after { transform: scaleX(1); }
.profile-panel:not([hidden]) { animation: panel-in .28s cubic-bezier(.25, 1, .5, 1); }

/* Right now */
.dialog-body .now-facts { grid-template-columns: 76px minmax(0, 1fr); gap: 6px 14px; margin: 0 0 20px; font-size: 13px; }
.now-said { margin: 0 0 24px; padding: 2px 0 2px 16px; border-left: 2px solid var(--line); font: italic 16px/1.6 Georgia, serif; color: var(--accent); }
.now-meters { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 32px; margin-bottom: 20px; }
.now-block .meter { grid-template-columns: 64px minmax(0, 1fr) 44px; font-size: 11px; }
.now-block .meter > :last-child { text-align: right; font-variant-numeric: tabular-nums; }
.now-block .feeling { margin-top: 8px; font-size: 13px; }
.under-the-hood { margin-top: 4px; border-top: 1px solid var(--line); }
.under-the-hood > summary { display: flex; align-items: center; gap: 10px; padding: 14px 0; cursor: pointer; font-size: 12px; font-weight: 600; color: var(--dim); }
.under-the-hood > summary::-webkit-details-marker { display: none; }
.under-the-hood > summary::before { content: '▸'; font-size: 11px; transition: transform .2s cubic-bezier(.25, 1, .5, 1); }
.under-the-hood[open] > summary::before { transform: rotate(90deg); }
.under-the-hood > summary .badge { margin: 0; }
.under-the-hood[open] > summary { color: var(--text); }
.under-the-hood .profile-label { margin-top: 20px; }
.under-the-hood .kv { grid-template-columns: 112px minmax(0, 1fr); }
.under-the-hood .bar, .under-the-hood .meter { grid-template-columns: 168px minmax(0, 1fr) 44px; font-size: 11px; }

/* Their story: set like a page of the chronicle, with the facts of their life beneath. */
.story-prose { max-width: 62ch; font: 17px/1.75 Georgia, serif; color: var(--text); text-wrap: pretty; }
.story-prose p + p { margin-top: 12px; }
.story-prose p:first-child::first-letter { float: left; padding: 7px 10px 0 0; font: 400 3.4em/.8 'DM Serif Display', Georgia, serif; color: var(--accent); }
.story-facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 22px 36px; margin: 30px 0 0; padding-top: 24px; border-top: 1px solid var(--line); }
.story-facts dt { margin-bottom: 6px; font-size: 10px; font-weight: 700; letter-spacing: 1.4px; text-transform: uppercase; color: var(--dim); }
.story-facts dd { margin: 0; font-size: 13px; line-height: 1.6; }
.story-facts ul { margin: 0; padding: 0; list-style: none; }
.story-facts li { position: relative; padding-left: 14px; }
.story-facts li::before { content: '·'; position: absolute; left: 2px; font-weight: 700; color: var(--stamp, var(--gold)); }
.story-also { display: block; font-size: 12px; color: var(--dim); }

/* Personality: the approved card, read as a person rather than a form. */
.personality-lead { max-width: 62ch; font: italic 16px/1.6 Georgia, serif; }
.personality-lead .profile-label { font-style: normal; font-family: 'DM Sans', sans-serif; }
.trait-stamps { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 32px; margin: 20px 0 0; padding: 0; list-style: none; }
.trait-stamps li { display: grid; gap: 4px; font-size: 13px; line-height: 1.5; color: var(--dim); }
.stamp { justify-self: start; padding: 2px 7px 1px; font-size: 11px; font-weight: 700; letter-spacing: 1.2px; text-transform: uppercase; color: var(--stamp, var(--gold)); border: 1.5px solid currentColor; border-radius: 4px; transform: rotate(-1.2deg); }
.trait-stamps li:nth-child(even) .stamp { transform: rotate(.9deg); }
.trait-stamps li:nth-child(3n) .stamp { transform: rotate(-.4deg); }
.personality-block { margin-top: 30px; }
.neighbours { display: grid; gap: 10px; margin: 0; padding: 0; list-style: none; }
.neighbours li { display: grid; grid-template-columns: 136px minmax(0, 1fr); gap: 14px; align-items: center; font-size: 13px; line-height: 1.5; }
.neighbour { display: inline-flex; justify-self: start; align-items: center; gap: 9px; max-width: 100%; padding: 4px 12px 4px 4px; font-size: 13px; color: var(--text); background: var(--paper); border: 1px solid var(--line); border-radius: 999px; }
.neighbour:hover { background: var(--control); border-color: var(--accent); }
.neighbour b { font-weight: 600; white-space: nowrap; }
.profile-avatar { display: inline-grid; place-items: center; flex-shrink: 0; width: 28px; height: 28px; font-size: 12px; object-fit: cover; object-position: center 28%; background: var(--control); border-radius: 50%; }
.neighbours p { margin: 0; }
.personality-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 32px; }
.moods { display: grid; gap: 10px; margin: 0; }
.moods dt { font-size: 12px; font-weight: 600; color: var(--text); }
.moods dd { margin: 0; font-size: 13px; line-height: 1.55; color: var(--dim); }
.personality-manner section + section { margin-top: 14px; }
.personality-manner p, .personality-grid p { font-size: 13px; line-height: 1.6; }
.personality-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 20px 32px; margin-top: 30px; padding-top: 24px; border-top: 1px solid var(--line); }

.profile-empty { display: grid; justify-items: center; gap: 12px; padding: 40px 16px 32px; text-align: center; color: var(--dim); border: 1px dashed var(--line); border-radius: 14px; }
.profile-empty-mark { font-size: 32px; line-height: 1; color: #a5b894; }
.profile-empty p { max-width: 40ch; font-size: 14px; }

@keyframes profile-in { from { opacity: 0; transform: translateY(8px); } }
@keyframes panel-in { from { opacity: 0; transform: translateY(6px); } }
@keyframes note-in { from { opacity: 0; transform: translateY(4px); } }
@media (prefers-reduced-motion: reduce) {
  .profile, .profile-panel:not([hidden]), .profile-note-text.is-new { animation: none; }
  .village-roll .agent-chip, .village-roll .agent-chip:hover { transition: none; transform: none; }
  .profile-tabs [role=tab]::after { transition: none; }
}
@media (prefers-color-scheme: dark) {
  :root { --stamp: #d6b687; }
}

/* Narrow dialogs: the roll scrolls sideways, and the model sits beside what they are doing. */
@media (max-width: 760px) {
  .village-roll { margin-bottom: 20px; }
  .village-roll .agents { grid-auto-flow: column; grid-template-columns: none; grid-auto-columns: 112px; margin: 0 -20px; padding: 2px 20px 8px; overflow-x: auto; scroll-snap-type: x mandatory; scroll-padding-inline: 20px; scrollbar-width: thin; }
  .village-roll .agent-chip { padding: 12px 6px 10px; scroll-snap-align: start; }
  .village-roll .agent-portrait { width: 48px; height: 48px; }
  .profile { grid-template-columns: minmax(0, 1fr); gap: 18px; }
  .profile-figure { position: static; flex-direction: row; align-items: center; gap: 18px; }
  .profile-figure .person-model { flex: 0 0 136px; }
  .profile-figure .villager-viewer { width: 136px; height: 184px; }
  .profile-name { font-size: 34px; }
  .profile-tabs { gap: 20px; overflow-x: auto; scrollbar-width: none; }
  .profile-tabs [role=tab] { min-height: 44px; white-space: nowrap; }
  .now-meters, .story-facts, .trait-stamps, .personality-pair { grid-template-columns: minmax(0, 1fr); gap: 20px; }
  .neighbours li { grid-template-columns: minmax(0, 1fr); gap: 6px; }
  .under-the-hood .bar, .under-the-hood .meter { grid-template-columns: 120px minmax(0, 1fr) 40px; }
}

/* ------------------------------------------------------------------ *
 * Village reactions, visual (specs/015-village-reactions-visual): the one overhead signal per
 * villager lives in the existing bubble. Emotes and needs are round badges without a tail; a
 * happening thought carries its icon before the line. Motion is set per frame by overhead-view.js,
 * so reduced motion needs nothing here but a still need icon.
 * ------------------------------------------------------------------ */
/* The slot sits above its anchor, so a signal never covers its villager's name label (FR-019). */
#view .bubble { translate: 0 calc(-50% - 8px); }
.bubble .signal-icon { display: inline-flex; width: 22px; height: 22px; flex: none; transform-origin: 50% 80%; }
.bubble .signal-icon[hidden] { display: none; }
.bubble .signal-icon svg { width: 100%; height: 100%; display: block; }
.bubble.signal { padding: 4px; border-radius: 50%; line-height: 0; box-shadow: 0 2px 0 #3a50301f; }
.bubble.signal::after { display: none; }
.bubble.signal > div { display: none; }
.bubble.signal-emote .signal-icon { width: 26px; height: 26px; }
.bubble.signal-need { background: #fffbedd9; padding: 3px; }
.bubble.signal-need .signal-icon { width: 18px; height: 18px; animation: signal-bob 4s ease-in-out infinite; }
.bubble.thought-bubble.has-icon { display: flex; align-items: center; gap: 6px; text-align: left; }
.bubble.thought-bubble.has-icon .signal-icon { width: 20px; height: 20px; }
.bubble.thought-bubble.icon-only { padding: 4px; border-radius: 50%; }
.bubble.thought-bubble.icon-only > div { display: none; }
@keyframes signal-bob { 0%, 100% { translate: 0 0; } 50% { translate: 0 -3px; } }
@media (prefers-reduced-motion: reduce) { .bubble.signal-need .signal-icon { animation: none; } }
@media (max-width: 720px) {
  .bubble.signal { scale: .85; }
  .bubble.thought-bubble.has-icon { font-size: 10px; max-width: 125px; }
}

/* Letters from beyond the last stone (specs/019): the post dialog, the letter box count, the card row. */
.post-button { position: relative; }
.post-unread { display: inline-grid; place-items: center; min-width: 18px; height: 18px; padding: 0 5px; margin-left: 4px; font-size: 11px; font-weight: 700; line-height: 1; color: #fff8ea; background: #a8473a; border-radius: 9px; }
.post-unread[hidden] { display: none; }
.post-dialog .dialog-body { overflow: auto; }
.post-lede, .post-hint { font-size: 14px; line-height: 1.55; color: var(--dim); margin: 0 0 14px; }
.post-small { font-size: 12.5px; color: var(--dim); margin: 6px 0; }
.post-note { font-size: 13.5px; padding: 10px 12px; background: var(--paper); border: 1px solid var(--line); border-radius: 10px; }
.post-error { font-size: 13.5px; color: #9c3b2f; margin: 8px 0; }
.post-field { display: grid; gap: 6px; margin: 0 0 12px; font-size: 13px; font-weight: 600; }
.post-field input, .post-field textarea { font: 15px/1.55 Georgia, 'Iowan Old Style', serif; color: var(--text); background: var(--reading); border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; width: 100%; box-sizing: border-box; }
.post-field textarea { resize: vertical; min-height: 150px; background-image: repeating-linear-gradient(transparent 0 23px, #d9d2bf55 23px 24px); background-attachment: local; }
.post-consent { display: flex; gap: 10px; align-items: flex-start; font-size: 13px; line-height: 1.5; color: var(--dim); margin: 0 0 14px; }
.post-consent input { margin-top: 3px; }
.post-primary { padding: 10px 18px; font-weight: 700; color: #fff8ea; background: #7a4a24; border: 0; border-radius: 10px; cursor: pointer; }
.post-primary:disabled { opacity: .55; cursor: default; }
.post-tabs { display: flex; gap: 6px; margin: 0 0 16px; border-bottom: 1px solid var(--line); }
.post-tab { padding: 8px 14px; font-weight: 600; color: var(--dim); background: transparent; border: 0; border-bottom: 2px solid transparent; cursor: pointer; }
.post-tab[aria-selected="true"] { color: var(--text); border-bottom-color: #7a4a24; }
.post-from { display: flex; align-items: center; gap: 10px; margin: 0 0 14px; font-size: 13.5px; color: var(--dim); }
.post-seal { display: inline-grid; place-items: center; width: 34px; height: 34px; font: 700 12px Georgia, serif; color: #fbe7d6; background: radial-gradient(circle at 35% 35%, #c45a4a, #8e2f25); border-radius: 50%; box-shadow: inset 0 0 0 3px #a8473a, 0 1px 2px #0003; }
.post-seal-label { font-style: italic; color: var(--text); }
.post-villagers { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; margin: 0 0 14px; padding: 0; border: 0; }
.post-villagers legend { font-size: 13px; font-weight: 600; margin-bottom: 8px; }
.post-villager { display: grid; gap: 2px; padding: 10px 12px; background: var(--paper); border: 1px solid var(--line); border-radius: 10px; cursor: pointer; }
.post-villager input { position: absolute; opacity: 0; pointer-events: none; }
.post-villager:has(input:checked) { border-color: #7a4a24; box-shadow: inset 0 0 0 1px #7a4a24; }
.post-villager:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.post-villager.is-waiting { opacity: .55; cursor: default; }
.post-villager-name { font-weight: 700; }
.post-villager-role { font-size: 12px; color: var(--dim); }
.post-letter { padding: 14px 16px; margin: 0 0 12px; background: var(--paper); border: 1px solid var(--line); border-radius: 12px; }
.post-letter.is-unread { border-color: #a8473a; box-shadow: inset 3px 0 0 #a8473a; }
.post-letter header { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.post-letter h3 { font-size: 15px; margin: 0; }
.post-date { font-size: 12px; color: var(--dim); }
.post-status { font-size: 13px; color: var(--dim); margin: 4px 0 8px; }
.post-mine summary { font-size: 13px; cursor: pointer; color: var(--dim); }
.post-mine p, .post-mine blockquote { font: 14px/1.6 Georgia, serif; }
.post-mine blockquote { margin: 6px 0 0; padding-left: 10px; border-left: 3px solid var(--line); }
.post-reply { margin-top: 10px; padding: 14px 16px; font: 15px/1.65 Georgia, 'Iowan Old Style', serif; color: #2b2418; background: #f6edd6; border-radius: 8px; box-shadow: 0 1px 0 #d9c9a3, 0 6px 16px #3a2c1514; }
.post-reply p { margin: 0 0 10px; }
.post-enclosure { display: flex; align-items: center; gap: 8px; margin: 12px 0 0 !important; font: italic 13.5px Georgia, serif; color: #5a4a33; }
.post-enclosure-icon { width: 30px; height: 30px; flex: none; }
.post-settings { display: grid; gap: 10px; margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); font-size: 13px; }
.post-settings-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.post-danger { color: #9c3b2f; }
.mailbox-count { font: 600 10px 'DM Sans', sans-serif; letter-spacing: .4px; color: #fff7db; background: #6d3b26e6; border: 1px solid #f8e5c255; border-radius: 6px; padding: 3px 7px; white-space: nowrap; pointer-events: auto; cursor: pointer; box-shadow: 0 2px 6px #0003; }
.mailbox-count[hidden] { display: none; }
.mailbox-count:focus-visible { outline: 2px solid #fff7db; outline-offset: 2px; }
.profile-letters { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin: 10px 0 0; font-size: 13px; color: var(--dim); }
.profile-write { font-size: 12.5px; }
@media (prefers-color-scheme: dark) {
  .post-reply { color: #2b2418; }
  .post-error, .post-danger { color: #f0a597; }
}
:root { --icon-letters: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 6h18v12H3z'/%3E%3Cpath d='m3 6 9 7 9-7'/%3E%3C/svg%3E"); }
#top .observer-nav > [data-post-button] { --icon: var(--icon-letters); }
/* Write letter: the header's one warm, filled control, so visitors see a letter can be sent. The envelope shows
   at every width (the labelled bar hides the other nav icons), and the unread count is light on the brown. */
#top .observer-nav > .post-button { background: #7a4a24; border-color: #7a4a24; color: #fff8ea; }
#top .observer-nav > .post-button:hover { background: #623b1c; border-color: #623b1c; }
#top .observer-nav > .post-button::before { content: ''; }
#top .post-button .post-unread { background: #fff8ea; color: #7a4a24; box-shadow: 0 0 0 1px #7a4a24; }
@media (max-width: 1060px) {
  #top .post-button .post-unread { position: absolute; top: -6px; right: -4px; margin: 0; min-width: 16px; height: 16px; font-size: 10px; }
}
@media (max-width: 960px) {
  #top .post-button .post-unread { top: 3px; right: 3px; }
}
.post-closed { padding: 14px 16px; margin: 4px 0 6px; background: var(--paper); border: 1px solid var(--line); border-left: 4px solid #7a4a24; border-radius: 10px; font-size: 14px; }
.post-closed p { margin: 0 0 8px; }
.post-field textarea:disabled { opacity: .6; cursor: not-allowed; }
