/* flicks · ui pass, direction b · the sentence speaks.
   built against ui/direction_b/ · Main · TonightPhone · Ledger · RapidFire · Log.
   the ledger and rapid fire keep direction a's ruled-page discipline underneath.
   since FL-23 the map is the app and these four are the pages in its menu. the
   tonight surface and its rules are gone; the map block is at the foot.

   the grammar, in one line: one serif family, three inks, no boxes, no radius,
   no shadows, no colour. state is dotted against solid, never a fill. */

:root {
  --paper:      #fdfcf8;
  --ink:        #1c1b18;   /* 16.8 : 1 on paper */
  --ink-light:  #6b675c;   /* 5.5 : 1 on paper · the floor. never lighter for text */

  /* the one dark ground: the voyage on the channel (FL-33). mirrors voyage.js. */
  --sky:        #0b0b0d;

  --serif: "Crimson Pro", Georgia, "Times New Roman", serif;

  /* the page column, from the boards: 1280 wide, 56px side padding, 1168 of content */
  --pad: 56px;
  --col: 1280px;

  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 32px;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
/* the map is the window. a page from the menu scrolls inside itself. */
body { overflow: hidden; }

body {
  margin: 0;
  font: 400 17px/1.45 var(--serif);
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
}


a { color: var(--ink); }

/* the only motion in the file. reduced motion takes it away at the bottom. */
a, button, .chip, .btn, input, select, th, .sug {
  transition: color 150ms linear, border-color 150ms linear;
}

::placeholder { color: var(--ink-light); opacity: 1; }

/* --- the idioms, once ----------------------------------------------------- */

/* chips and nav share one state grammar: dotted and light when off,
   solid and dark when on. never a fill, never a background step. */
.chip, .filter select {
  font-family: var(--serif);
  font-size: 13px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-weight: 300;
  color: var(--ink-light);
  background: none;
  border: 0;
  border-bottom: 1px dotted var(--ink-light);
  border-radius: 0;
  padding: 14px 0 3px;
  min-height: 44px;
  min-width: 44px;
  display: inline-flex;
  align-items: flex-end;
  justify-content: center;
  cursor: pointer;
  text-align: center;
}
.chip[aria-pressed="true"],
.filter[data-on] select {
  color: var(--ink);
  font-weight: 500;
  border-bottom: 1px solid var(--ink);
}
.chip:hover, .filter select:hover { color: var(--ink); }

/* an action is an underlined word, never a box. */
.btn, .linkbtn {
  font: 400 14px/1.45 var(--serif);
  color: var(--ink);
  background: none;
  border: 0;
  border-radius: 0;
  padding: 0;
  min-height: 44px;
  min-width: 44px;
  display: inline-flex;
  align-items: center;
  /* left, not centre: min-width would otherwise indent a short word like "again"
     off the rule it sits under. */
  justify-content: flex-start;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
  white-space: nowrap;
}
.btn.primary { font-weight: 500; }
.btn:hover, .linkbtn:hover, a:hover { color: var(--ink-light); }

/* a key letter, always quiet, always beside the thing it drives. */
.k, .cardkeys, .keys { font-size: 12px; color: var(--ink-light); }
.cardkeys b, .keys b, .help dt { font-weight: 500; color: var(--ink); font-family: var(--serif); }

/* every field is a line, not a box. */
input[type="text"], select, textarea {
  font-family: var(--serif);
  color: var(--ink);
  background: none;
  border: 0;
  border-bottom: 1px solid var(--ink);
  border-radius: 0;
  padding: 6px 0 4px;
  min-height: 44px;
}
input:focus, select:focus, textarea:focus { outline: none; }

/* keyboard first, so focus is never guessed at. */
:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
input:focus-visible, select:focus-visible { outline-offset: 1px; }

/* --- a page over the map -------------------------------------------------- */
/* each page opens over the map and scrolls inside itself. esc goes back. */
.page {
  position: fixed; inset: 0; z-index: 50;
  background: var(--paper);
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  display: flex; flex-direction: column;
}
.page[hidden] { display: none; }
/* the menu button floats at the top right over every page, so the page's own bar
   keeps its right end clear of it. */
.page .bar { padding-right: max(var(--pad), 124px); }
.bar, .view, .foot {
  width: 100%;
  max-width: var(--col);
  margin: 0 auto;
}
.bar {
  display: flex;
  gap: 28px;
  align-items: flex-end;
  padding: 30px var(--pad) 22px;
  border-bottom: 1px solid var(--ink);   /* the section rule the boards draw */
}
.mark {
  margin: 0;
  font-size: 17px;
  font-weight: 600;
  color: var(--ink);
  padding-bottom: 6px;
  flex: none;
}
/* the page's name, where the tab row used to stand. the menu is the way between. */
.pagetitle {
  flex: 1; margin: 0; padding-bottom: 6px;
  font-size: 13px; font-weight: 500; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink); border: 0;
}
.baractions { display: flex; gap: 22px; align-items: flex-end; }
.baractions .btn {
  font-size: 13px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 300;
  color: var(--ink-light);
  text-decoration: none;
  border-bottom: 1px dotted var(--ink-light);
  align-items: flex-end;
  padding: 15px 0 3px;
}
.baractions .btn:hover { color: var(--ink); border-bottom: 1px solid var(--ink); }
#importfile { position: absolute; width: 1px; height: 1px; opacity: 0; padding: 0; min-height: 0; }

/* --- the view ------------------------------------------------------------- */
.view { flex: 1; padding: 0 var(--pad) 44px; }
.view:focus { outline: none; }

h2, h3 {
  margin: 0 0 var(--s3);
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-light);
}
h3 {
  margin: var(--s6) 0 var(--s3);
  border-top: 1px solid var(--ink);
  padding-top: var(--s3);
}
.muted { color: var(--ink-light); font-weight: 300; }
.hint {
  display: block; font-size: 14px; font-weight: 300; color: var(--ink-light);
  text-transform: none; letter-spacing: 0; max-width: 60ch;
}

/* --- the ask · one label, one row of chips -------------------------------- */
/* flex-start, not flex-end: when a chip row wraps, the label must stay on the
   first line. 23px drops the label's text onto the first chip's baseline. */
.row { display: flex; align-items: flex-start; gap: 26px; }
.rowlabel {
  width: 84px;
  flex: 0 0 84px;
  padding-top: 23px;
  font-size: 13px;
  letter-spacing: 0.04em;
  color: var(--ink-light);
}
.rowlabel .hint { display: none; }   /* FL-5 took the chip row hints off the screen */
.chips { display: flex; flex-wrap: wrap; column-gap: 26px; row-gap: 0; flex: 1; }
.go { display: flex; align-items: center; gap: 22px; }
.logcol .go, .rapidstart .go, .profile .go { padding-top: var(--s5); }

/* wikipedia · ebert · nyt. the dots come from css, so the markup stays as it is. */
.reads { display: flex; align-items: baseline; flex-wrap: wrap; row-gap: 24px; }
.reads a, .titlelink {
  font-size: 13px; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--ink-light); text-decoration: underline; text-underline-offset: 3px;
}
.reads a:not(:last-child)::after {
  content: ' · '; text-decoration: none; display: inline-block; padding: 0 6px;
}
/* this is a row of links under the title, not three words in a sentence, so each
   one is a 44px target at every width. the equal negative margin keeps the ruled
   row exactly where it was, the way .titlelink does it. */
.reads a {
  /* inline-block, not inline-flex: the css dot after each link has to stay on the
     word's own baseline, and a flex item would centre it in the 44px box instead. */
  display: inline-block; min-height: 44px; min-width: 44px;
  padding: 12px 0; margin: -12px 0;
}
.titlelink {
  font-size: inherit; text-transform: none; letter-spacing: 0; color: var(--ink);
  /* the dotted rule has to follow the word, not the box, so it is the text
     decoration and not a border. dotted off, solid on, like every other state. */
  text-decoration: underline; text-decoration-style: dotted;
  text-decoration-color: var(--ink-light); text-underline-offset: 3px;
  /* 99 of these sit in the ledger. the padding makes each one a 44px target;
     the equal negative margin keeps the ruled row exactly where it was. */
  display: inline-block; padding: 12px 0; margin: -12px 0;
  /* jaws, duel, boy and kimi are four letters wide. the box is 44 whatever the
     word is; the column is set by the longest title, so no row moves. */
  min-width: 44px;
}
.titlelink:hover { text-decoration-style: solid; text-decoration-color: var(--ink); }

/* --- log ------------------------------------------------------------------ */
/* the board splits this surface into two columns under the section rule. */
.logform {
  padding-top: 34px;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 56px;
  max-width: 1168px;
}
.logform > h2 { grid-column: 1 / -1; }
.logcol { display: flex; flex-direction: column; min-width: 0; }
.logcol .row { flex-direction: column; align-items: stretch; gap: var(--s1); padding-top: var(--s4); }
.logcol .row:first-child { padding-top: 0; }
.logcol .rowlabel {
  width: auto; flex: none; padding-top: 0;
  font-size: 13px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-light);
}
/* the right column keeps the label-and-chips row from the ask panel. */
.logcol.chipcol .row {
  flex-direction: row; align-items: flex-start; gap: 26px;
  padding-top: 0; padding-bottom: 12px;
}
.logcol.chipcol .rowlabel { width: 84px; flex: 0 0 84px; padding-top: 23px; text-transform: lowercase; }
.logcol.chipcol .row.stack { flex-direction: column; align-items: stretch; gap: var(--s1); padding-top: 30px; }
.logcol.chipcol .row.stack .rowlabel { width: auto; flex: none; padding-top: 0; text-transform: uppercase; }
.logcol.chipcol .go { padding-top: 30px; }

.field { position: relative; flex: 1; min-width: 0; }
.field.inline { display: flex; align-items: flex-end; gap: 28px; flex-wrap: wrap; }
#title, #score { font-size: 31px; font-weight: 300; line-height: 1.2; }
#title { width: 100%; max-width: 420px; }
#score { width: 120px; }
#note { width: 100%; max-width: 420px; font-size: 17px; font-weight: 300; color: var(--ink-light); }

.sugs {
  position: absolute; z-index: 5; top: 100%; left: 0; width: 100%; max-width: 420px;
  margin: 0; padding: 0; list-style: none;
  background: var(--paper);
}
.sug {
  display: flex; gap: 16px; align-items: baseline; justify-content: space-between;
  padding: 10px 0; min-height: 44px; cursor: pointer;
  border-bottom: 1px dotted var(--ink-light);
  font-size: 16px; font-weight: 500;
}
.sug[aria-selected="true"] { border-bottom: 1px solid var(--ink); }
.sug .muted { font-size: 13px; letter-spacing: 0.04em; text-transform: uppercase; font-weight: 400; }

.pending { grid-column: 1 / -1; margin-top: var(--s6); }
.plain { list-style: none; margin: 0; padding: 0; }
.plain li {
  padding: 10px 0; border-bottom: 1px dotted var(--ink-light);
  min-height: 44px; display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap;
}
.plain li .muted { font-size: 13px; letter-spacing: 0.04em; text-transform: uppercase; font-weight: 400; }

/* --- rapid fire ----------------------------------------------------------- */
.rapidstart, .summary, .card { padding-top: 40px; max-width: 1168px; }
.cardcount, .cardyear {
  font-size: 13px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-light);
}
/* the film data clicks small on one baseline beside the title, as the board draws it. */
.cardhead { display: flex; flex-wrap: wrap; align-items: baseline; gap: 18px; margin-top: 10px; }
.cardtitle {
  margin: 0; font-size: 28px; line-height: 1.2; font-weight: 600;
  color: var(--ink); text-transform: none; letter-spacing: 0;
}
.cardhook {
  margin: 10px 0 0;
  font-size: 31px; line-height: 1.24; font-weight: 300; color: var(--ink-light);
  max-width: 30ch; text-wrap: pretty;
}
.card .reads { margin: 0; }
.card .buffer { margin-top: var(--s5); }
.buffer {
  font-size: 31px; line-height: 1.2; font-weight: 300; color: var(--ink-light);
  border-bottom: 1px solid var(--ink);
  width: 120px; padding: 6px 0 4px; min-height: 44px;
}
.cardkeys { margin-top: var(--s4); }
.cardtouch { display: none; }
.touchscore { width: 120px; font-size: 17px; font-weight: 300; text-align: center; }
.rapidstart p, .summary p { max-width: 60ch; }
.summary .plain li { display: block; }
.summary .plain b { font-weight: 500; }

/* --- ledger · direction a's ruled table under direction b's type ---------- */
.filters { display: flex; column-gap: 26px; row-gap: 0; flex-wrap: wrap; align-items: flex-start; }
/* the select and the check are both 44px boxes, so their underlines land on one
   line. any padding on the label itself would push the select down off it. */
.filter {
  display: inline-flex; align-items: flex-end; gap: var(--s2);
  padding: 0; min-height: 44px;
  font-size: 13px; letter-spacing: 0.04em;
  color: var(--ink-light); font-weight: 400; cursor: pointer;
}
.filter select {
  appearance: none; -webkit-appearance: none;
  min-width: 72px; text-align: left; justify-content: flex-start;
}
.filter.check {
  border-bottom: 1px dotted var(--ink-light);
  padding: 14px 0 3px; min-width: 44px;
  font-size: 13px; letter-spacing: 0.12em; text-transform: uppercase; font-weight: 300;
}
.filter.check:has(input:checked) { color: var(--ink); font-weight: 500; border-bottom: 1px solid var(--ink); }
.filter.check:has(input:focus-visible) { outline: 2px solid var(--ink); outline-offset: 3px; }
.filter.check input { position: absolute; width: 1px; height: 1px; opacity: 0; margin: 0; }

.chartbox { padding: 26px 0 0; }
.chartbox h3 { border-top: 0; padding-top: 0; margin-top: 0; }
.chartbox > .muted, .chartbox > .hint { max-width: 80ch; font-size: 14px; font-weight: 300; }
/* the strip sits in the same scroll box the table uses. below 700 it keeps its
   own width and the box scrolls sideways, so the labels never scale down. */
.chart { width: 100%; min-width: 700px; height: auto; display: block; margin: var(--s4) 0 var(--s2); }
.chart .rule { stroke: var(--ink); stroke-width: 1; }
.chart .tick { stroke: var(--ink-light); stroke-width: 1; }
.chart .at { stroke: var(--ink-light); stroke-width: 1; stroke-dasharray: 2 3; }
.chart .lab { font: 400 12px var(--serif); fill: var(--ink-light); letter-spacing: 0.04em; }
.chart .dot { fill: none; stroke: var(--ink); stroke-width: 1; }
.chart .dot.loved { fill: var(--ink); stroke: none; }
/* the eleven he loved and never scored cannot plot, so they get a ruled line. */
.lovedline { border-top: 1px solid var(--ink); padding-top: var(--s3); margin-top: var(--s5); }
.lovedline p { margin: 0; font-size: 17px; font-weight: 300; color: var(--ink-light); max-width: 80ch; }

.tablewrap { max-width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.table { width: 100%; border-collapse: collapse; margin-top: var(--s4); }
.table th {
  text-align: left;
  font: 400 13px/1.45 var(--serif);
  letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-light);
  padding: 10px var(--s4) 10px 0;
  border-bottom: 1px solid var(--ink);           /* the head row is the solid rule */
  cursor: pointer; white-space: nowrap; height: 44px;
}
.table th:hover { color: var(--ink); }
.table th[aria-sort="descending"]::after { content: ' \2193'; color: var(--ink); }
.table th[aria-sort="ascending"]::after { content: ' \2191'; color: var(--ink); }
.table td {
  padding: 10px var(--s4) 10px 0;
  border-bottom: 1px dotted var(--ink-light);    /* row rules are dotted */
  vertical-align: baseline; height: 44px;
  font-size: 16px; font-weight: 500;
}
.table tr:hover td { border-bottom: 1px solid var(--ink); }
.table .num {
  font-variant-numeric: tabular-nums; font-size: 13px; font-weight: 400;
  color: var(--ink-light); text-transform: uppercase; letter-spacing: 0.04em;
}
.table .num.score { font-size: 15px; font-weight: 600; color: var(--ink); text-transform: none; letter-spacing: 0; }
.table .love { font-style: italic; font-weight: 400; font-size: 15px; color: var(--ink); text-transform: none; letter-spacing: 0; }
.table .when, .table .with {
  font-size: 13px; font-weight: 400; color: var(--ink-light);
  text-transform: uppercase; letter-spacing: 0.04em;
}
.table .note { font-size: 14px; font-weight: 300; color: var(--ink-light); max-width: 32ch; }
/* the board opens each ledger row with a quiet number. it is a count, not a sort key. */
.table .rowno { width: 36px; }
.table td.rowno {
  font-size: 12px; font-weight: 400; color: var(--ink-light);
  letter-spacing: 0.04em; padding-right: var(--s3);
}
.table td:first-child .muted { font-size: 13px; text-transform: uppercase; letter-spacing: 0.04em; }

#ledgerbody { margin-top: var(--s5); border-top: 1px solid var(--ink); padding-top: var(--s3); }
#ledgerbody > .muted { font-size: 13px; letter-spacing: 0.04em; text-transform: uppercase; font-weight: 400; }

/* --- profile -------------------------------------------------------------- */
.profile { padding-top: 34px; max-width: 900px; }
.weights { display: flex; flex-direction: column; }
.weight {
  display: grid; grid-template-columns: minmax(0, 1fr) 200px 48px;
  gap: var(--s4); align-items: center;
  padding: 6px 0; min-height: 44px;
  border-bottom: 1px dotted var(--ink-light);
}
.wlabel { color: var(--ink); font-size: 16px; }
.wslide { width: 200px; accent-color: var(--ink); min-height: 44px; }
.wval { font-size: 13px; color: var(--ink-light); text-align: right; font-variant-numeric: tabular-nums; }
.rule { max-width: 60ch; font-style: italic; font-weight: 400; color: var(--ink); }
.owed { color: var(--ink-light); font-size: 14px; font-weight: 300; max-width: 80ch; }
.confirm { margin-top: var(--s4); border-top: 1px dotted var(--ink-light); padding-top: var(--s3); max-width: 60ch; }
.btn.danger { font-style: italic; }
/* the words the map did not know. a list to read, one word a row. */
.misses { list-style: none; margin: 0; padding: 0; max-width: 80ch; }
.misses li { padding: 6px 0; border-bottom: 1px dotted var(--ink-light); font-size: 15px; }

/* --- the page foot and the keys overlay ---------------------------------- */
.foot {
  display: flex; justify-content: space-between; align-items: center; gap: var(--s4);
  padding: var(--s3) var(--pad);
  border-top: 1px solid var(--ink);
  color: var(--ink-light); font-size: 12px; min-height: 40px;
}
.status { color: var(--ink); font-size: 13px; }
.help {
  position: fixed; right: 16px; bottom: 16px; width: 380px; z-index: 70;
  max-height: calc(100vh - 32px); overflow-y: auto;
  background: var(--paper);
  border: 1px solid var(--ink);
  padding: var(--s4) var(--s5) var(--s5);
}
.help h2 { margin-bottom: var(--s3); }
.help dl { display: grid; grid-template-columns: 148px 1fr; gap: var(--s2) var(--s4); margin: 0; }
.help dt { font-size: 13px; }
.help dd { margin: 0; color: var(--ink-light); font-size: 14px; font-weight: 300; }

/* --- the phone · 700px and under · TonightPhone.dc.html -------------------- */
@media (max-width: 700px) {
  :root { --pad: 20px; }

  body { font-size: 16px; line-height: 1.4; }

  .bar { padding: 16px var(--pad) 10px; gap: 12px; flex-wrap: wrap; align-items: baseline; }
  .page .bar { padding-right: 80px; }
  .mark { font-size: 16px; padding-bottom: 0; }
  .baractions { margin-left: auto; gap: 16px; align-items: baseline; }
  .baractions .btn { font-size: 12px; letter-spacing: 0.1em; padding: 14px 0 3px; }

  .view { padding: 0 var(--pad) var(--s5); }

  /* the app's chip labels are longer than the phone board's, so a row wraps.
     the padding keeps a wrapped line nearer its own label than the next one. */
  .row { gap: 14px; flex-wrap: wrap; padding-bottom: 12px; }
  .rowlabel { width: 56px; flex: 0 0 56px; padding-top: 24px; font-size: 12px; }
  .chips { column-gap: 14px; }
  .chip, .filter.check { font-size: 12px; letter-spacing: 0.1em; }
  .btn { font-size: 15px; }

  .logform { grid-template-columns: minmax(0, 1fr); gap: 0; padding-top: 24px; }
  .logcol.chipcol .row, .logcol.chipcol .row.stack {
    flex-direction: column; align-items: stretch; gap: var(--s1); padding-top: var(--s4);
  }
  .logcol.chipcol .rowlabel { width: auto; flex: none; padding-top: 0; }
  .logcol.chipcol .go { padding-top: var(--s5); }

  .rapidstart, .summary, .card, .profile { padding-top: 24px; }
  .cardtitle { font-size: 24px; }
  .cardhook { font-size: 24px; }
  .cardkeys { display: none; }
  .cardtouch { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 18px; margin-top: var(--s4); }

  .weight { grid-template-columns: minmax(0, 1fr) 48px; }
  .wslide { grid-column: 1 / -1; width: 100%; }

  .filters { gap: 16px; }
  .table th, .table td { padding-right: var(--s3); }

  .foot { padding: var(--s2) var(--pad); }
  .keys { display: none; }

  /* a page's status line sits at the foot of the screen and takes no room when
     it is empty. the map's own lines live in its legend and its card. */
  .page .status {
    position: fixed; left: 0; right: 0; z-index: 51;
    bottom: 0; padding: var(--s2) var(--pad) calc(var(--s2) + env(safe-area-inset-bottom));
    background: var(--paper);
    border-top: 1px dotted var(--ink-light);
  }
  .page .status:empty { display: none; }

  /* 16px stops ios zooming the page when a field takes focus. */
  #note, .touchscore,
  .filter select, input[type="text"], select, textarea { font-size: 16px; }
  #title, #score { font-size: 24px; }

  .sugs { width: 100%; max-width: 100%; }

  .help {
    left: 0; right: 0; width: auto;
    bottom: 0;
    max-height: 60vh; overflow-y: auto;
    border-left: 0; border-right: 0; border-bottom: 0;
    padding: var(--s4) var(--pad);
  }
  .help dl { grid-template-columns: 120px 1fr; }
}

/* ---------------------------------------------------------------------------
   the map · the expanse. wireframe pass, ruled by nobody yet.

   the canvas fills the window and three boxes float over it: the bar, the menu
   and the card. each is opaque with a hairline (FL-22). a see-through card is
   parked by nevil and banned by the hygiene skill; this pass keeps them opaque.

   two inks only, and they are the app's own: --ink and --ink-light. state is
   dotted against solid, the same grammar as everywhere else. every hairline
   clears 3 : 1 and every label clears 4.5 : 1 on the paper.

   this block is deliberately outside the direction b grammar above. it is system
   font, hairlines and one grey, so the map reads as unfinished geometry and not
   as a designed surface. direction b gets to rule it in a later pass, and when it
   does, this whole block is replaced, not extended.
   --------------------------------------------------------------------------- */

.wire, .fmenuwrap {
  font: 13px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  letter-spacing: 0;
  text-transform: none;
}
.wire *, .fmenuwrap * { font-family: inherit; }

/* a class that sets display must give the hidden attribute its say back. */
.expanse [hidden], .fmenu[hidden] { display: none !important; }

.expanse { position: fixed; inset: 0; background: var(--paper); overflow: hidden; }
.fcanvas {
  position: absolute; inset: 0; display: block; width: 100%; height: 100%;
  cursor: crosshair; touch-action: none;
}

/* the three floating boxes and the legend. opaque, one hairline, no shadow. */
.fbarbox, .fcard, .fmenubtn, .fmenu, .fhover {
  background: var(--paper);
  border: 1px solid var(--ink-light);
  border-radius: 0;
}

/* the bar · one box for a title and for a night. its answer drops under it. */
.fbarbox {
  position: absolute; top: 16px; left: 16px; z-index: 10;
  width: min(520px, calc(100vw - 160px));
}
.fbarbox:focus-within { border-color: var(--ink); }
.wire .fbar-in {
  display: block; width: 100%; max-width: none;
  border: 0; padding: 0 var(--s3); min-height: 44px; font-size: 14px;
}
.fdrop {
  border-top: 1px solid var(--ink-light);
  padding: var(--s2) var(--s3) var(--s3);
  max-height: min(460px, calc(100vh - 110px)); overflow-y: auto;
}
.fdrop p { margin: var(--s2) 0 0; }
.freadback { padding-bottom: var(--s1); }
.fgates { display: flex; flex-wrap: wrap; gap: var(--s2); align-items: center; }
.fgates .wire-dim { margin: 0; }

/* a row is a whole film: the title, then its why line in his own numbers. */
.frows { list-style: none; margin: var(--s2) 0 0; padding: 0; }
.frow {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  width: 100%; min-height: 44px; padding: 6px 0;
  background: none; border: 0; border-top: 1px dotted var(--ink-light); border-radius: 0;
  color: var(--ink); text-align: left; font-size: 13px; cursor: pointer;
}
.frows li:first-child .frow { border-top: 0; }
.frow:hover .frow-title, .frow:focus .frow-title { text-decoration: underline; text-underline-offset: 2px; }
.frow-head { display: flex; gap: var(--s2); align-items: baseline; }
.frow-no { font-weight: 600; min-width: 1ch; }
.frow-title { font-weight: 600; }
.frow-why { display: block; color: var(--ink-light); font-size: 12px; line-height: 1.4; }

/* the card · at the right, under the menu, never over the film it shows. */
.fcard {
  position: absolute; top: 72px; right: 16px; z-index: 10;
  width: 340px; max-height: calc(100vh - 112px); overflow-y: auto;
  padding: var(--s3);
}
.fcard-head { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--s2); }
.fcard-head .wire-h { margin: 12px 0 var(--s1); }
#cardstatus { margin: var(--s2) 0 0; color: var(--ink); }

/* the menu · top right. flicks is the first word in it. */
.fmenuwrap { position: fixed; top: 16px; right: 16px; z-index: 60; }
.fmenubtn {
  font-size: 12px; color: var(--ink); cursor: pointer;
  min-height: 44px; min-width: 44px; padding: 0 var(--s3);
}
.fmenubtn:hover, .fmenubtn[aria-expanded="true"] { border-color: var(--ink); }
.fmenu {
  position: absolute; top: 52px; right: 0; width: 220px;
  display: flex; flex-direction: column; padding: var(--s2);
}
.fmenu-mark { margin: var(--s1) var(--s2) var(--s2); font-weight: 600; color: var(--ink); }
.fmenu-item {
  display: flex; justify-content: space-between; align-items: center;
  min-height: 44px; padding: 0 var(--s2);
  background: none; border: 0; border-radius: 0; color: var(--ink);
  font-size: 13px; text-align: left; cursor: pointer;
}
.fmenu-item:hover { text-decoration: underline; text-underline-offset: 2px; }
.fmenu-key { color: var(--ink-light); font-size: 12px; }

/* the one quiet line at the foot: the count, the marks, the geometry. it runs the
   width of the window on its own ground, so no node or label crowds it (FL-25). */
.flegend {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 5;
  margin: 0; padding: 6px 16px;
  background: var(--paper); border-top: 1px solid var(--ink-light);
  color: var(--ink-light); font-size: 11px;
}
.flegend .status { color: var(--ink); margin-right: var(--s2); }
.expanse .status:empty { display: none; }

.fhover {
  position: absolute; pointer-events: none; z-index: 12;
  padding: var(--s1) var(--s2); max-width: 280px;
}
/* the hover is the name and one line. the line is cut, never wrapped (FL-25). */
.fhover .fhover-name, .fhover .fhover-line {
  margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* the score before a revision, beside the one he holds now. */
.table td.score .was { font-size: 11px; font-weight: 400; }

/* the pieces inside the boxes. grey boxes on purpose, not the direction b look. */
.wire h3.wire-h {
  font-size: 15px; font-weight: 600; color: var(--ink);
  margin: 0 0 var(--s2); text-transform: none; letter-spacing: 0; border-top: 0; padding-top: 0;
}
.wire-h4 {
  font-size: 12px; font-weight: 600; margin: var(--s4) 0 var(--s1);
  text-transform: none; letter-spacing: 0; color: var(--ink-light);
}
.wire-dim { color: var(--ink-light); margin: 0 0 var(--s2); }
.wire-line, .wire-tone { margin: 0 0 var(--s2); }
.wire-meta { color: var(--ink-light); margin: 0 0 var(--s2); }

.wire-chip {
  font-size: 12px; color: var(--ink-light);
  background: none; border: 1px dotted var(--ink-light); border-radius: 0;
  padding: 0 var(--s2); min-height: 44px; min-width: 44px; cursor: pointer;
}
.wire-chip[aria-pressed="true"] { color: var(--ink); border: 1px solid var(--ink); }

.wire-btn {
  font-size: 12px; color: var(--ink);
  background: var(--paper); border: 1px solid var(--ink-light); border-radius: 0;
  padding: 0 var(--s3); min-height: 44px; min-width: 44px; cursor: pointer;
}
.wire-btn:hover { border-color: var(--ink); }

.wire-a {
  font: inherit; color: var(--ink); background: none; border: 0; border-radius: 0;
  padding: 0; min-height: 44px; min-width: 44px; text-align: left; cursor: pointer;
  display: inline-flex; align-items: center;
  text-decoration: underline; text-underline-offset: 2px;
}
.wire-links { display: flex; flex-wrap: wrap; gap: var(--s3); margin: 0 0 var(--s2); }
.wire-links a { min-height: 44px; min-width: 44px; display: inline-flex; align-items: center; }
.wire-list { list-style: none; margin: 0 0 var(--s2); padding: 0; }
.wire-list li { display: flex; align-items: center; gap: var(--s1); min-height: 44px; }
.wire-list .wire-dim { display: inline; margin: 0; }

.wire-in {
  font-size: 13px; color: var(--ink); background: var(--paper);
  border: 1px solid var(--ink-light); border-radius: 0;
  padding: var(--s2); min-height: 44px; width: 100%; max-width: 100%;
}
.wire-in:focus { outline: none; border-color: var(--ink); }

.wire-acts { display: flex; flex-wrap: wrap; gap: var(--s2); margin: 0 0 var(--s2); }
.wire-reason { display: flex; gap: var(--s2); align-items: center; margin: 0 0 var(--s2); }

/* the FL-5 row. the score is a short field, the note takes the width of the card. */
.wire-scorerow { display: flex; flex-wrap: wrap; gap: var(--s2); align-items: center; margin: 0 0 var(--s2); }
.wire-scorerow .wire-scorein { width: 76px; }
.wire-scorerow .wire-notein { width: 100%; }

/* the runtime, last on the card, folded behind the words that say it is owed. */
.wire-fold { margin-top: var(--s2); }
.wire-runtime { display: flex; flex-wrap: wrap; gap: var(--s2); align-items: center; margin-top: var(--s2); }
.wire-runtime .wire-runtimein { width: 172px; }

/* the phone · the bar across the top, the menu beside it, the card a sheet from
   the bottom to half the screen. the map stays live behind it. */
@media (max-width: 700px) {
  .fbarbox { top: 8px; left: 8px; right: 76px; width: auto; }
  .fmenuwrap { top: 8px; right: 8px; }
  .fmenubtn .fkey { display: none; }
  .fdrop { max-height: 40vh; }
  .expanse.card-open .fdrop { display: none; }
  .fcard {
    top: auto; right: 0; left: 0; bottom: 0;
    width: auto; height: 50vh; max-height: 50vh;
    border-left: 0; border-right: 0; border-bottom: 0;
    padding-bottom: calc(var(--s3) + env(safe-area-inset-bottom));
  }
  .flegend { padding: 4px 8px calc(4px + env(safe-area-inset-bottom)); }
  .wire .fbar-in, .wire-in { font-size: 16px; }
}

/* nothing moves for anyone who asked for that. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition: none !important; animation: none !important; scroll-behavior: auto !important;
  }
}

/* ---------------------------------------------------------------------------
   the channel · the tv page (FL-32). a page from the menu, in direction b.
   watched is solid and not yet watched is dotted, the same pair as the chips.
   the only marks are ◆, finale week, dark days, owed and end.
   --------------------------------------------------------------------------- */
.channel { padding-top: 14px; max-width: 1168px; outline: none; }
.tvmarks { margin: 0 0 var(--s2); }
/* the voyage. the one dark surface in the app, full width of the column. */
.tvvoyage { display: block; width: 100%; height: 280px; background: var(--sky); margin: 0 0 var(--s5); }
.tvtop { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 300px); column-gap: 56px; }
.tvtop > .tvpart:only-child { grid-column: 1 / -1; }
.tvmark {
  font-size: 13px; letter-spacing: 0.14em; text-transform: uppercase; font-weight: 500;
  color: var(--ink); border-bottom: 1px solid var(--ink); padding-bottom: 2px;
}
.tvpart { margin-bottom: var(--s4); }
.tvpart > h2, .tvtool > h2 { border-top: 1px solid var(--ink); padding-top: var(--s2); margin-bottom: 0; }

.tvlistings { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; column-gap: 36px; row-gap: 0; }
.tvlisting { display: flex; align-items: baseline; gap: 14px; min-height: 44px; }
.tvlisting .tvname { font-size: 20px; font-weight: 300; }
.tveps { display: inline-flex; gap: 12px; }
.ep {
  font-size: 15px; color: var(--ink-light); font-weight: 400;
  border-bottom: 1px dotted var(--ink-light); padding-bottom: 1px;
}
.ep.done { color: var(--ink); font-weight: 500; border-bottom: 1px solid var(--ink); }
.tvcoming { margin: 0; min-height: 44px; display: flex; align-items: center; font-size: 15px; font-weight: 300; }

.tvrows { display: flex; flex-direction: column; }
.tvrow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 96px 64px 64px 64px 72px 44px;
  column-gap: 20px; align-items: end;
  border-bottom: 1px dotted var(--ink-light);
}
.tvrow > * { min-height: 44px; display: flex; align-items: flex-end; padding-bottom: 6px; }
.tvrow .btn { padding-bottom: 0; }
.tvhead { border-top: 1px solid var(--ink); border-bottom: 1px solid var(--ink); padding-top: var(--s2); }
.tvhead > h2 { margin: 0; min-height: 22px; padding-bottom: 2px; }
.tvhead > span { font-size: 12px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-light); min-height: 22px; padding-bottom: 2px; }
.tvrow .tvname { font-size: 19px; font-weight: 400; }
.tvkind, .tvseason { font-size: 13px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-light); }
.tvrow .tvmark { align-self: end; margin-bottom: 6px; min-height: 0; display: inline; }
.tvnum { width: 56px; font-size: 17px; text-align: left; }
.tvoff { color: var(--ink-light); }

.tvtools { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 56px; margin-bottom: var(--s4); }
.tvline { display: flex; flex-wrap: wrap; align-items: flex-end; column-gap: 22px; row-gap: var(--s2); }
#tvcatch { font-size: 17px; max-width: 260px; }
#tvadd { font-size: 19px; width: 170px; }
.tvline .chips { flex: none; column-gap: 14px; }

.tvseasonrow { grid-template-columns: minmax(0, 1fr) 64px 64px 72px minmax(0, 1.4fr); }
.tvnote { width: 100%; font-size: 15px; font-weight: 300; color: var(--ink-light); }

@media (max-width: 700px) {
  .channel { padding-top: 12px; }
  .tvvoyage { height: 230px; margin-bottom: var(--s4); }
  .tvtop { grid-template-columns: minmax(0, 1fr); }
  .tvlisting .tvname { font-size: 20px; }
  .tvrow { grid-template-columns: minmax(0, 1fr) 52px 52px 44px 44px; column-gap: 8px; }
  .tvrow .tvkind, .tvrow .tvseason, .tvhead > :nth-child(2), .tvhead > :nth-child(3) { display: none; }
  .tvseasonrow { grid-template-columns: minmax(0, 1fr) 52px 64px; }
  .tvseasonrow .tvnote { grid-column: 1 / -1; }
  .tvtools { grid-template-columns: minmax(0, 1fr); row-gap: var(--s4); }
  .tvnum, #tvcatch, #tvadd { font-size: 16px; }
}
