/*
 * The page's L13 interface: the top bar, its tips, the phone's line. UI_SPEC v10 §7.1, §7.2, §7.3;
 * L13 plan §3.2, §3.3 ("CSS for new UI goes to apps/web/ui.css"), §3.6.
 *
 * Linked after index.html's own <style>, so a rule here of the same weight wins; the colours are
 * index.html's tokens (--ink, --edge, …). scripts/deploy-world.sh copies this file beside the page.
 */

/* --- the top bar (§7.1) ----------------------------------------------------------------------- */

/* One line (plan §3.2, "#banner (one line)"): the items never wrap. What the line has no room for
   is left out a group at a time (ui.ts `fit`, `.tb-over`) and listed behind More, which shows only
   then (`#banner.tb-overflow`); the review of 28 September found the bar on three lines at 1024 px. */
#banner { position: relative; align-items: center; gap: 4px 12px; flex-wrap: nowrap; }
#banner > .name { flex: none; }
#world {
  display: flex; flex: 0 1 auto; flex-wrap: nowrap; align-items: center; min-width: 0; overflow: hidden; color: var(--ink2);
  /* Room inside the clip for a term's focus ring (outline-offset 2px), given back by the margin. */
  padding: 4px 3px; margin: -4px -3px;
}
#world .tb-item.tb-over { display: none; }
.tb-item { display: inline-flex; align-items: center; white-space: nowrap; }
/* The dots between items are drawn here, so an item the phone hides takes nothing with it, and a
   screen reader reads none of them ("·" / ""). The share follows its count with a dash. */
.tb-item + .tb-item::before { content: "·" / ""; color: var(--ink3); margin: 0 .5em; }
.tb-item.tb-share::before { content: "—" / ""; }

/* A term: words that open their tip (tips.ts). It reads as text with a dotted underline, not as a
   button's box, and the pointer says there is something to read. */
.term {
  font: inherit; color: inherit; background: none; border: 0; margin: 0; padding: 0;
  cursor: help; text-align: inherit;
  text-decoration: underline dotted rgba(242, 242, 239, .32); text-underline-offset: 3px;
}
.term:hover, .term.tip-open { color: var(--ink); text-decoration-color: var(--ink2); }
.term:focus-visible { outline: 1px solid var(--yolk); outline-offset: 2px; border-radius: 3px; }
#banner > .name { color: var(--ink); font-weight: 600; letter-spacing: .02em; text-decoration: none; }
#world .tb-year .term, #world .tb-alive .term { color: var(--ink); font-weight: 600; }
#world .tb-era .term { color: var(--blood); }
.clock { display: inline-flex; align-items: center; gap: 4px; }
.clock-glyph { flex: none; }

/* The live and Chronicle pills, at the bar's right end: clear of the open Chronicle, which used to
   cover its own pill (both sat in the first column of the overlay). */
#banner-end { flex: none; margin-left: auto; display: inline-flex; align-items: center; gap: 8px; }
#topbar-more, #topbar-rest { display: none; }
/* More, on the desktop: only when the line has left something out; its panel lists exactly that,
   under the button at the bar's right end, and stops above the minimap (ui.ts, D12). */
#banner.tb-overflow #topbar-more {
  display: inline-flex; flex: none; align-items: center; gap: 6px; padding: 2px 10px;
  font: inherit; font-size: 12px; color: var(--ink2); background: none; cursor: pointer;
  border: 1px solid var(--edge); border-radius: 999px;
}
#topbar-more[aria-expanded="true"] { color: var(--ink); border-color: rgba(242, 242, 239, .35); }
#topbar-more:focus-visible { outline: 1px solid var(--yolk); outline-offset: 2px; }
#topbar-rest:not([hidden]) {
  display: block; position: absolute; top: 100%; right: 12px; z-index: 5; min-width: 220px; max-width: 360px;
  margin: 4px 0 0; padding: 4px 0; list-style: none; overflow-y: auto;
  background: #0b0c0e; border: 1px solid rgba(242, 242, 239, .22); border-radius: 10px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, .55);
}
.tb-row + .tb-row { border-top: 1px solid var(--edge); }
.tb-row .term { display: flex; align-items: center; width: 100%; min-height: 32px; padding: 0 14px; text-align: left; color: var(--ink); white-space: nowrap; }

/* --- the Today line and the alerts (§5.1; today.ts) -------------------------------------------------- */

/* A solid strip under the top bar (D12: nothing translucent over the map), one sentence. Its names
   are links to their cards; before the first answer a quiet word, after a failed one "not updating". */
#today { flex: 0 0 auto; position: relative; z-index: 3; background: var(--black); border-bottom: 1px solid var(--edge); }
#today-line, #alerts .alerts-today { margin: 0; color: var(--ink2); font-size: 12.5px; line-height: 18px; }
#today-line { padding: 5px 12px; }
#today-line a[data-card], #alerts .alerts-today a[data-card] {
  color: var(--ink); text-decoration: underline; text-decoration-color: var(--ink3); text-underline-offset: 2px;
}
.today-quiet, .today-stale { color: var(--ink3); }
.today-failed { color: var(--ink2); }
#today .retry, #alerts .retry {
  margin-left: 6px; font: inherit; font-size: 12px; color: var(--ink); background: none; cursor: pointer;
  border: 1px solid var(--edge); border-radius: 999px; padding: 1px 10px;
}
#today-strip { display: none; }

/* The alerts: the right dock, above the minimap (the grid keeps them apart), worst first. A folded
   list is its count alone; so is a list an open card needs the room of (today.ts `layout`). */
#alerts {
  grid-column: 2; grid-row: 1 / span 2; align-self: start; justify-self: end;
  width: 320px; max-height: 100%; min-height: 0; overflow-y: auto;
  background: #08090b; border: 1px solid var(--edge); border-radius: 10px; font-size: 12px; line-height: 1.45;
}
#alerts.none, #alerts .alerts-today { display: none; }
#alerts.folded { width: auto; }
#alerts.folded #alerts-list { display: none; }
#alerts-fold {
  display: flex; align-items: center; gap: 6px; width: 100%; padding: 6px 10px; font: inherit; font-size: 11px;
  letter-spacing: .04em; text-transform: uppercase; color: var(--yolk); background: none; border: 0; cursor: pointer; text-align: left;
}
#alerts-fold::after { content: "▾" / ""; margin-left: auto; color: var(--ink3); }
#alerts-fold[aria-expanded="false"]::after { content: "▸" / ""; }
#alerts-list { list-style: none; margin: 0; padding: 0; }
.alert {
  display: flex; flex-wrap: wrap; align-items: flex-start; gap: 4px 8px; padding: 6px 10px 6px 8px;
  border-top: 1px solid var(--edge); border-left: 3px solid var(--ink3);
}
.alert.sev-3 { border-left-color: var(--blood); }
.alert.sev-2 { border-left-color: #f08a3c; }
.alert-go, .alert-still { flex: 1 1 0; min-width: 0; text-align: left; font: inherit; color: var(--ink); }
.alert-go { background: none; border: 0; padding: 0; cursor: pointer; }
.alert-go:hover, .alert-go.tip-open { text-decoration: underline; text-decoration-color: var(--ink3); text-underline-offset: 2px; }
.alert-go:focus-visible, .alert-why:focus-visible, #alerts-fold:focus-visible { outline: 1px solid var(--yolk); outline-offset: 2px; }
.alert-still { color: var(--ink2); }
.alert-why {
  flex: none; width: 18px; height: 18px; padding: 0; border-radius: 50%; font: inherit; font-size: 11px; line-height: 16px;
  color: var(--ink3); background: none; border: 1px solid var(--edge); cursor: help;
}
.alert-why:hover, .alert-why.tip-open { color: var(--ink); border-color: var(--ink3); }
.alert-places { flex-basis: 100%; list-style: none; margin: 2px 0 0; padding: 0 0 0 10px; }
.alert-places li { padding: 1px 0; }
.alert-places a { color: var(--ink2); text-decoration: underline; text-decoration-color: var(--ink3); text-underline-offset: 2px; }
.alert-more { font: inherit; color: var(--ink3); background: none; border: 0; padding: 0; cursor: pointer; text-decoration: underline dotted; }

/* --- tips (tips.ts) ----------------------------------------------------------------------------- */

.tip {
  position: fixed; z-index: 20; max-width: min(340px, calc(100vw - 16px));
  background: #0b0c0e; border: 1px solid rgba(242, 242, 239, .22); border-radius: 8px;
  padding: 8px 10px; color: var(--ink2); font-size: 12px; line-height: 1.5;
  box-shadow: 0 6px 20px rgba(0, 0, 0, .55);
}
.tip p { margin: 0 0 4px; }
.tip p:last-child { margin-bottom: 0; }
.tip b { color: var(--ink); font-weight: 600; }
.tip .term { color: var(--ink); }
/* A term and the punctuation after it: one piece, never split by a line break (glossary.ts). */
.nobr { white-space: nowrap; }
/* A tip with no room beside its list (an alert's reason on the phone): in its row, under its line,
   so it covers none of the rows after it (tips.ts). */
.tip.tip-inline { position: static; flex: 1 0 100%; max-width: none; margin: 2px 0 4px; box-shadow: none; }

/* --- the phone (§7.3): one line of at most 48 px; the rest opens on tap ------------------------- */

@media (max-width: 720px), (pointer: coarse) and (max-width: 900px) {
  #banner { height: 48px; padding: 0 8px 0 10px; flex-wrap: nowrap; gap: 6px; }
  /* One line, whatever it holds: never wrapped, cut at the end if a world ever outgrows it. The
     world's own state has the line; the wordmark is the More panel's first row. */
  #world { display: block; flex: 1 1 auto; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 12px; }
  /* The 44 px terms leave 3 px of the bar's 47 (48, less its border). The desktop's 4 px of room
     above and below the line for a focus ring made it 52 px, 2.5 px past the bar's bottom (50 px of
     content in 47, the first CI of l13v). Here that room is 1 px, and the 1 px ring lies in it,
     against the term. */
  #world { padding-top: 1px; padding-bottom: 1px; margin-top: -1px; margin-bottom: -1px; }
  #world .term:focus-visible { outline-offset: 0; }
  #world .tb-item { vertical-align: middle; }
  #world .tb-rest { display: none; }
  #world .tb-item + .tb-item::before { margin: 0 .35em; }
  #banner > .name { display: none; }
  /* Each term on the line is a 44 px target (§7.3); the dots between them keep them apart. */
  #world .term { min-width: 44px; min-height: 44px; display: inline-flex; align-items: center; justify-content: center; }
  /* The live and Chronicle pills float over the map's top left, where they always were on the
     phone: fixed, above the map (a positioned #stage would paint over them), and out of the bar's
     own height. While the open Chronicle has that corner, they give it up; its × closes it. */
  #banner-end { position: fixed; top: calc(48px + 44px + 16px); left: 16px; z-index: 3; margin: 0; }
  body:has(#chronicle.open) #banner-end { display: none; }
  #topline { justify-content: flex-end; }
  #topbar-more, #banner.tb-overflow #topbar-more {
    display: inline-flex; flex: none; align-items: center; justify-content: center; gap: 6px;
    min-width: 44px; min-height: 44px; padding: 0 10px;
    font: inherit; font-size: 12px; color: var(--ink2); background: none; cursor: pointer;
    border: 1px solid var(--edge); border-radius: 10px;
  }
  #topbar-rest:not([hidden]) { left: 8px; right: 8px; min-width: 0; max-width: none; max-height: calc(100vh - 80px); }
  .tb-row .term { min-height: 44px; white-space: normal; }

  /* §7.3 (B12): "The Today line and alerts take one collapsible strip; no ticker." One 44 px button:
     the sentence cut at its end, and how many alerts. Pressed, the whole sentence and the alerts
     open under it, over the map (a panel until the phone has bottom sheets, L13 step 4). */
  #today { height: 44px; border-bottom: 0; box-shadow: inset 0 -1px 0 var(--edge); }
  #today-line { display: none; }
  #today-strip {
    display: flex; align-items: center; gap: 10px; width: 100%; height: 44px; padding: 0 12px;
    font: inherit; font-size: 12px; color: var(--ink2); background: none; border: 0; text-align: left; cursor: pointer;
  }
  .strip-text { flex: 1 1 auto; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
  .strip-count { flex: none; color: var(--yolk); font-size: 11px; letter-spacing: .04em; text-transform: uppercase; }
  .strip-count::after { content: " ▾" / ""; color: var(--ink3); }
  #today-strip[aria-expanded="true"] .strip-count::after { content: " ▴" / ""; }
  #alerts, #alerts.none { display: none; }
  #alerts.open {
    display: block; position: fixed; top: calc(48px + 44px); left: 8px; right: 8px; z-index: 6; width: auto;
    max-height: calc(100dvh - 48px - 44px - 16px); margin-top: 4px;
    background: #0b0c0e; border: 1px solid rgba(242, 242, 239, .22); box-shadow: 0 6px 20px rgba(0, 0, 0, .55);
  }
  #alerts.folded #alerts-list { display: block; }
  #alerts .alerts-today { display: block; padding: 10px 14px; }
  #alerts .retry { display: inline-flex; align-items: center; min-height: 44px; margin: 4px 0 0; }
  #alerts-fold { display: none; }
  /* 44 px targets, 8 px apart (§7.3): the rows' padding keeps one alert's buttons clear of the next's. */
  .alert { align-items: center; padding: 4px 8px 4px 10px; }
  .alert-go, .alert-still { display: flex; align-items: center; min-height: 44px; }
  .alert-why { width: 44px; height: 44px; border-radius: 10px; font-size: 13px; }
  .alert-places { margin-top: 4px; }
  .alert-places a { display: flex; align-items: center; min-height: 44px; }
  .alert-places li + li { margin-top: 8px; }
  .alert-more { min-height: 44px; }
}
