/* assets/calendar.css — the calendar page's own stylesheet, on top of app.css.
   Moved out of calendar.html on 3 Sep 2026 for the same reason as
   assets/universe.css: the page is a shell, its code is a stamped asset that
   caches for a year. Loaded after app.css. */
/* ============================================================
   CALENDAR LAYER · R1 (2026-08-09) — the diary as a data table.

   Same 451 events, same five columns, same chip vocabulary, same
   palette and same voice. What changes is that the thing now
   BEHAVES like a table.

   Measured faults this closes (build/audit.py --sel body
   --url .../calendar.html):
     · 12 overflow defects at 390px, and they were not cosmetic.
       table-layout:fixed carried 136 + 224 + 74px of hard column
       widths into a 390px viewport, so the EVENT column — the only
       auto column — was crushed to ~0 and the first event's name
       was set ONE LETTER PER LINE, forty lines tall, with the date
       and the chips overprinting each other. The table now reflows
       on a phone into a true two-column grid (a date rail and an
       event stack) instead of being squeezed into one, and
       TYPE · ACCESS — which the old phone rule simply deleted —
       comes back with it.
     ·  0 focus rings anywhere on the page: eight region chips, the
       verified toggle, ten form fields and the submit button all
       took focus invisibly (the fields changed a 1px border and
       nothing else). One ring now, on everything.
     · 27px filter chips and 40px form fields at 390 → 44px.
     · light theme's VERIFIED green: the live --up-l is #12734D
       (app.css readability layer), 5.86:1 on white at 9.5px.

   And the craft the reference (markets.ft.com) actually has:
     · the countdown is a FIGURE COLUMN — header IN, values 5D /
       18D / NOW, right-aligned, tabular. It was left-aligned prose
       ("IN 5D") under a blank header.
     · every date and every count is tabular-nums, so the date rail
       is a rail and not a ragged edge.
     · zebra banding and a row highlight, because a 1,124px row with
       five columns cannot be tracked across by eye on hairlines.
     · the column header is a tinted band, not four faint words
       floating over the first row.
     · each month band carries its own count, so the grouping tells
       you how big it is before you read it.

   NOT sticky, and header.chrome above documents why: `html, body
   { overflow-x: hidden }` is set site-wide, which makes BODY the
   scroll container, and a sticky child pins inside its scroll
   container — which never scrolls; the viewport does. Measured the
   same way the chrome layer measured it. So instead of a header
   that silently fails to pin, every month re-states its columns:
   the labels are never more than one month-group away.
   ============================================================ */

  :root {
    /* three surfaces, in order: page · zebra · header band. The zebra is a
       band you read THROUGH, the header a plate you read ON — so the header
       is --panel2 and the zebra sits between it and the page. Every text
       token used inside the table clears AA on all three, measured.

       CONTINUITY: these were four literal hexes that each already had a token
       holding the identical colour — #13314A IS --panel2 (and its light twin
       #E6F1FB is --panel2's light value too), #3EC78F IS --up-l, and the zebra
       was --panel off by seven in the last channel, a difference no eye
       resolves but every future palette edit would have had to remember. They
       now point at the tokens, so the diary repaints when the wire does. The
       one value that stays literal is the light VERIFIED green, which is a
       measured contrast fix and not a copy of anything. */
    --cl-zebra: var(--panel);
    --cl-head:  var(--panel2);
    --cl-ok:      var(--up-l);
    --cl-ok-line: color-mix(in srgb, var(--up-l) 45%, transparent);
    --cl-t1-line: color-mix(in srgb, var(--brand) 50%, transparent);
  }
  /* No light-theme override. One was scoped here (#0F7A4F, 5.36:1) against
     --up-l #178a5d at 4.35:1 — but that is app.css's head-block value, which
     the READABILITY LAYER re-declares as #12734D: 5.86:1 on white, better
     than the override it was replaced by. The diary inherits the live one. */

  /* CONTINUITY: 20px is the terminal's page gutter (.main). The diary was at
     18 and the phone at 10 against the terminal's 12 — two pages of one
     publication whose text started two pixels apart. */
  .cl-shell { max-width: 1160px; margin: 0 auto; padding: 24px 20px 70px; }

  /* ---- the page head: masthead, then the stamp as a meta strip ---- */
  .cl-head h1 { font-family: var(--serif); font-weight: 600; font-size: 30px;
                letter-spacing: -.01em; line-height: 1.15; }
  .cl-head .sub { font-size: 13.5px; color: var(--text-dim); margin-top: 6px;
                  max-width: 660px; line-height: 1.5; }
  .cl-stamp {
    display: flex; flex-wrap: wrap; align-items: center; column-gap: 8px; row-gap: 3px;
    font-family: var(--mono); font-size: var(--fs-sub); letter-spacing: var(--ls-mono);
    color: var(--faint);
    text-transform: uppercase; margin-top: 14px; padding-top: 10px;
    border-top: 1px solid var(--rule);
    font-variant-numeric: tabular-nums lining-nums;
  }
  .cl-stamp b { color: var(--cl-ok); font-weight: 600; }
  .cl-stamp .s { color: var(--grid); }

  /* ---- the filter bar: same chips, finger-sized ---- */
  /* The controls are the terminal's, not this page's own: --field on --panel,
     the same 1px --grid border and the same focus colour the universe page and
     the desk use, so a reader who has typed into one has typed into all three. */
  .cl-find { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 16px 0 0; }
  .cl-find input, .cl-find select {
    padding: 9px 11px; border: 1px solid var(--grid); border-radius: 6px;
    background: var(--field); color: var(--text); font: inherit; font-size: 13px;
    max-width: 100%;
  }
  /* min-width:0 on both: a flex item will not shrink below its content by
     default, and the vertical list holds strings like "COUNTER-UAS". That is
     what pushed a select past the edge of a 375px screen on the universe page
     and clipped its own dropdown arrow. */
  .cl-find input { flex: 1 1 260px; min-width: 0; }
  .cl-find select { max-width: 210px; min-width: 0; }
  .cl-find input:focus, .cl-find select:focus { outline: none; border-color: var(--brand-l); }
  /* Borderless, like the universe page's — a reset is not a filter and should
     not look like one sitting in a row of them. */
  .cl-clear { background: none; border: 0; color: var(--brand); font: inherit;
    font-size: 12.5px; cursor: pointer; padding: 6px 4px; }
  .cl-clear:hover { text-decoration: underline; }
  @media (max-width: 720px) { .cl-clear { min-height: 44px; padding: 0 10px; } }
  .cl-count { font-family: var(--mono); font-size: 11px; color: var(--faint);
    letter-spacing: .06em; margin: 8px 0 0; }
  .cl-count b { color: var(--text); }
  .cl-filters { display: flex; gap: 6px; flex-wrap: wrap; margin: 14px 0 4px; }
  .cl-filters .pill {
    display: inline-flex; align-items: center; gap: 7px;
    min-height: 32px; padding: 0 13px;
    border: 1px solid var(--pill-line); border-radius: 999px;
    background: transparent; color: var(--text-dim);
    font-family: var(--sans); font-size: 13px; font-weight: 500; line-height: 1;
    white-space: nowrap; cursor: pointer;
    transition: background-color .12s, border-color .12s, color .12s;
  }
  .cl-filters .pill:hover { background: var(--panel2); border-color: var(--brand-d); color: var(--text); }
  .cl-filters .pill.active {
    background: var(--brand-d); border-color: var(--brand-d); color: #fff;
    box-shadow: 0 0 0 1px var(--brand-d);
  }
  /* CONTINUITY: 11px, the size the terminal's identical filter chip prints
     its count at. This chip is a copy of .pillbar .pill in every other
     respect; the count was the one value that drifted. */
  .cl-filters .pill .n {
    font-family: var(--mono); font-size: var(--fs-sub); color: var(--text-dim);
    font-variant-numeric: tabular-nums lining-nums;
  }
  /* the terminal's opaque count plate: rgba white composites to 4.52:1 on
     #1D6BB4, this is 4.77:1 and it is the same ink on both pages. */
  .cl-filters .pill.active .n { color: #E7F0FA; }

  /* ---- month grouping: a band with its own count ---- */
  .cl-mgroup { margin-top: 26px; }
  /* CONTINUITY: this band is the diary's section head — the same role as
     DFT WIRE in the rail and INDEX MOVERS on the desk, which both print at
     12px/.1em. It was the only mono label on either page tracked at .16em,
     and its count line the only sub-line at 10.5px. */
  .cl-month {
    display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
    font-family: var(--mono); font-size: var(--fs-sec); letter-spacing: var(--ls-mono);
    color: var(--brand-l); text-transform: uppercase; margin: 0 0 7px;
    /* an h2 now, for the heading list — the band keeps its own weight and
       spacing rather than the user agent's bold and top margin */
    font-weight: inherit;
  }
  /* the month bands stack down the page and each carries a year — a column of
     figures read vertically, like every other one on both pages */
  .cl-month .mname { font-variant-numeric: tabular-nums lining-nums; }
  .cl-month .mn {
    letter-spacing: var(--ls-mono); font-size: var(--fs-sub); color: var(--text-dim);
    font-variant-numeric: tabular-nums lining-nums; white-space: nowrap;
  }

  /* ---- the table ---- */
  table.cl { width: 100%; border-collapse: collapse; font-size: 13.5px; table-layout: fixed; }
  table.cl col.c-date  { width: 118px; }
  /* the two chip columns were cut to the old 10px/6px chip. On the wire's
     chip they were ~20px short and STATUS · TIER · VERTICAL started wrapping
     its third chip, which is the one thing a 448-row table cannot afford —
     a ragged row height is what stops the eye running down a column. The
     event name gives up the width; it already carries a second line. */
  table.cl col.c-flags { width: 266px; }
  table.cl col.c-type  { width: 234px; }
  table.cl col.c-in    { width: 62px; }
  table.cl th {
    text-align: left; font-family: var(--mono); font-size: var(--fs-col); font-weight: 600;
    letter-spacing: var(--ls-mono); color: var(--text-dim); text-transform: uppercase;
    padding: 7px 10px; background: var(--cl-head);
    border-top: 1px solid var(--grid); border-bottom: 1px solid var(--grid);
  }
  table.cl th.c-in { text-align: right; }
  table.cl td {
    padding: 8px 10px; border-bottom: 1px solid var(--rule);
    vertical-align: top; overflow-wrap: break-word;
  }
  /* Zebra, not row-hover, does the cross-row tracking — the same choice the
     reference makes. A full-row highlight would also over-promise: the row is
     not clickable on a pointer device, only the event name is. */
  table.cl tbody tr:nth-child(even) { background: var(--cl-zebra); }

  .cl-date {
    font-family: var(--mono); font-size: 11.5px; font-weight: 500;
    color: var(--brand-l); white-space: nowrap;
    font-variant-numeric: tabular-nums lining-nums;
  }
  /* an unconfirmed window is dimmer but still AA — it used --faint,
     which lands at 4.2:1 once a row is highlighted */
  .cl-date.est { color: var(--text-dim); font-weight: 400; }

  /* CONTINUITY: -.005em is the tracking every other 13.5px/600 Inter item
     name on the terminal carries (.trk .nm, .dk .co, .rel .t). This one was
     the only one left at normal. */
  .cl-name { display: inline-block; font-weight: 600; line-height: 1.3;
             letter-spacing: -.005em; }
  .cl-name:hover { color: var(--brand-l); }
  .cl-city { display: block; color: var(--text-dim); font-size: 12px; margin-top: 2px; }
  /* AQ-408: the Universe entry the event belongs to. */
  .cl-org { display: block; color: var(--text-dim); font-size: 12px; margin-top: 2px; }
  .cl-org a { color: var(--brand-l); text-decoration: none; }
  .cl-org a:hover { text-decoration: underline; }

  .chips { display: flex; flex-wrap: wrap; gap: 4px; }
  /* CONTINUITY: the wire's rectangular data chip, to the pixel — the same
     object as the feed's SOURCE / figure / price chips and the docket's form
     chip, which is how a reader crossing from the terminal to the diary knows
     it is still reading the same instrument. It was r6 / 10px / 6px of side
     padding against their r4 / 10.5px / 7px. Borders and hues are untouched:
     those carry the meaning (green = verified, blue = tier 1). */
  .cl-chip {
    display: inline-flex; align-items: center; min-height: var(--chip-h);
    font-family: var(--mono); font-size: var(--chip-fs);
    letter-spacing: var(--ls-chip); line-height: 1;
    font-variant-numeric: tabular-nums lining-nums;
    border: 1px solid var(--grid); border-radius: var(--r-chip);
    padding: 0 var(--chip-px);
    color: var(--text-dim);
  }
  /* AQ-665: a label wider than its cell wraps inside its chip. The columns
     below were sized to the forked wire's widest labels, and nowrap let the
     energy vocabulary ("TECHNICAL & EXECUTIVE CONFERENCE", "ADVANCED NUCLEAR
     & FUSION") run out of the cell and, at 834px, widen the page. A label that
     fits stays one line at the same 19px height and baseline (the padding is
     inside --chip-h), so nothing that fitted moves. */
  .cl-chip { padding-block: 2px; }
  /* 600, the weight the feed's emphasised chip already uses. 700 was a third
     rung on a two-rung chip scale. */
  .cl-chip.t1 { color: var(--brand-l); border-color: var(--cl-t1-line); font-weight: 600; }
  .cl-chip.ok { color: var(--cl-ok); border-color: var(--cl-ok-line); font-weight: 600; }
  /* Tobias, 27 Sep 2026: an unconfirmed next edition, shown where the last
     one fell. Dashed: a place held, not a date. */
  .cl-chip.tbc { border-style: dashed; font-weight: 600; }

  .cl-in {
    font-family: var(--mono); font-size: 11.5px; color: var(--text-dim);
    white-space: nowrap; text-align: right;
    font-variant-numeric: tabular-nums lining-nums;
  }
  /* the one value in the column that is not a figure is the one that matters */
  .cl-in.now { color: var(--brand-l); font-weight: 600; }

  .cl-note { margin-top: 26px; line-height: 1.7; }

  /* ---- submit form ---- */
  .cl-submit { margin-top: 44px; border-top: 1px solid var(--grid); padding-top: 10px; }
  /* the table wants 1,124px; a text field does not. The form keeps a form's
     measure instead of stretching every input to the width of the diary. */
  .cl-submit .sub, .cl-submit form { max-width: 820px; }
  .cl-grid { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 12px 14px; }
  .cl-submit label { display: block; font-family: var(--mono); font-size: 10px;
                     letter-spacing: .1em; color: var(--text-dim); text-transform: uppercase; }
  .cl-submit .opt { text-transform: none; letter-spacing: 0; color: var(--faint); }
  .cl-submit input, .cl-submit select, .cl-submit textarea {
    display: block; width: 100%; margin-top: 5px; padding: 8px 10px;
    background: var(--panel); border: 1px solid var(--grid); border-radius: 8px;
    color: var(--text); font: 400 13.5px/1.4 var(--sans);
  }
  .cl-submit input::placeholder { color: var(--faint); }
  .cl-submit input:hover, .cl-submit select:hover, .cl-submit textarea:hover { border-color: var(--pill-line); }
  .cl-notes { margin-top: 12px; }
  .cl-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin-top: 16px; }
  .cl-actions .btn.primary { min-height: 38px; }

  /* ---- one focus ring, on everything ------------------------------
     Nothing on this page had one. The fields set outline:none and
     moved a 1px border instead, which is not an indicator at 1px of
     --brand against --grid.

     CONTINUITY: the width, colour and offset now come from the same tokens
     the terminal's ring uses, and the radius follows the shape it is drawn
     round rather than sitting at a flat 6px — which put a rectangular ring
     around the region chips, and those are 999px pills. */
  .cl-shell :is(a, button, input, select, textarea):focus-visible {
    outline: var(--ring-w) solid var(--ring-c);
    outline-offset: var(--ring-o); border-radius: var(--r-row);
  }
  .cl-shell .cl-filters .pill:focus-visible { border-radius: var(--r-pill); }
  /* CONTINUITY: +1px was the diary's own offset, and .cl-name is 387 of the
     page's 400 tab stops — so the single most-focused control in the product
     rang at an offset used nowhere else. It takes the shared one. */
  .cl-shell .cl-name:focus-visible { outline-offset: var(--ring-o); border-radius: var(--r-chip); }

  /* ---- mid widths: the two chip columns give first --------------- */
  @media (max-width: 1040px) {
    table.cl col.c-flags { width: 224px; }
    table.cl col.c-type  { width: 186px; }
  }

  /* ---- tablet: they have to give again -----------------------------
     One step was not enough. The phone reflow only starts at 720px, so
     between 721 and ~830 the fixed table is still in force with 590px of
     hard column widths (118 + 224 + 186 + 62) against a ~681px table. That
     left EVENT — the only column carrying the thing the reader came for —
     at 91px at 721px, 114 at 744, 138 at 768, and the first row's
     "Oppenheimer Technology, Internet & Communications Conference" ran into
     the STATUS chips. iPad portrait is 768 and iPad mini is 744, so this is
     the middle of a real device band, not a sliver between breakpoints.

     Same principle as the step above, applied harder: the chip columns are
     fixed-content and shrink honestly, the event name cannot.

     The two chip widths are not round numbers because they are not guesses.
     .chips already wraps, so a column only clips when a SINGLE chip is wider
     than the cell, and the widest labels in the forked wire's type vocabulary
     measured 133px and 126px. Plus the cell's own padding that
     is 156 and 150 — the narrowest these columns can be without cutting a
     chip in half. Taking them lower did exactly that: 140px clipped the
     widest chip at 800 and 830px, trading one defect for another.
     RE-MEASURE once this wire's events database is populated: the TYPE
     vocabulary changed with the industry and every label is now shorter. */
  @media (max-width: 860px) {
    /* 112, not 104. The widest range in the database — "24 SEP – 3 OCT" —
       needs 107px of content plus this cell's 10px side padding, and .cl-date
       is nowrap, so 104 clipped five rows in the 768-834 band. Measured
       against all 448 date cells, not guessed: the same mistake as the TYPE
       column, made in the same commit, and it hid because build/audit.py only
       ever ran 1440 and 390 — the calendar's problem band is neither. */
    table.cl col.c-date  { width: 112px; }
    table.cl col.c-flags { width: 150px; }
    table.cl col.c-type  { width: 156px; }
    table.cl col.c-in    { width: 52px; }
  }

  /* ---- phone: the table REFLOWS, it does not shrink --------------
     The same reading order, in three real columns: the date rail, the
     event, the countdown — date and countdown still on one baseline,
     the two chip cells folded underneath and spanning. Every column
     survives; none is hidden, which is what the old rule did to
     TYPE · ACCESS. */
  @media (max-width: 720px) {
    .cl-shell { padding: 16px 12px 50px; }
    .cl-head h1 { font-size: 24px; }
    .cl-mgroup { margin-top: 22px; }

    /* CONTINUITY: the terminal's identical chip goes 13px/pad 13 → 12.5px/pad
       12 on a phone. This one used to hold 13px and GROW its padding to 15 —
       the same control moving in opposite directions on the two pages. The
       44px target is what a phone needs and it is untouched; only the type
       and the side padding now match the terminal's. */
    .cl-filters { gap: 6px; }
    .cl-filters .pill { min-height: 44px; padding: 0 12px; font-size: 12.5px; gap: 6px; }
    /* 16px on the fields, like every other text input on the wire at this
       width: iOS Safari zooms the whole page when a focused field is smaller,
       and the diary is the page you open standing up. */
    .cl-find input, .cl-find select { min-height: 44px; font-size: 16px; }
    .cl-find select { flex: 1 1 140px; max-width: none; }

    /* the diary rescaled 4 of its 36 type signatures at 390 where the terminal
       rescales 30 of 128 — so the event name and the date rail printed at
       their desktop size on a 390px screen while every comparable string on
       the terminal stepped down. (The chips step down with --chip-fs, which
       is now scaled once for both pages.) */
    .cl-name { font-size: 13px; }
    .cl-date, .cl-in { font-size: var(--fs-sub); }

    table.cl, table.cl thead, table.cl tbody { display: block; }
    table.cl colgroup { display: none; }

    /* Column headers cannot label a stack, so the header band becomes what
       it honestly is on a phone: the legend, in column order, all five
       labels kept rather than four of them dropped. */
    table.cl thead tr {
      display: block; padding: 7px 10px; background: var(--cl-head);
      border-top: 1px solid var(--grid); border-bottom: 1px solid var(--grid);
    }
    table.cl th {
      display: inline; padding: 0; border: 0; background: none; text-align: left;
    }
    table.cl th:not(:last-child)::after {
      content: "·"; color: var(--faint); padding: 0 4px;
    }

    table.cl tbody tr {
      display: grid; grid-template-columns: 74px minmax(0, 1fr) 36px;
      column-gap: 10px; row-gap: 5px; padding: 10px;
      border-bottom: 1px solid var(--rule); position: relative;
    }
    table.cl tbody td { display: block; padding: 0; border: 0; }
    table.cl td.c-date  { grid-area: 1 / 1; white-space: normal; }
    table.cl td.c-event { grid-area: 1 / 2; }
    table.cl td.c-in    { grid-area: 1 / 3; }
    table.cl td.c-flags { grid-area: 2 / 2 / 3 / 4; }
    table.cl td.c-type  { grid-area: 3 / 2 / 4 / 4; }
    table.cl td.c-flags:empty, table.cl td.c-type:empty { display: none; }

    .cl-grid { grid-template-columns: minmax(0,1fr); }
    .cl-submit input, .cl-submit select, .cl-submit textarea {
      font-size: 16px; min-height: 44px;
    }
    .cl-submit textarea { min-height: 88px; }
    .cl-actions .btn.primary { min-height: 44px; padding: 0 18px; }
  }

  /* ---- touch: the row IS the target ------------------------------
     A 17px event name is a 17px tap target. On a touch device the link
     is stretched over its whole row (100px+ tall, full width), which is
     the only way to get a finger target out of a dense diary without
     padding 451 rows to 44px each. Gated on `pointer: coarse` and not
     on width, because on a pointer device the same overlay would eat
     text selection across the row for no benefit. */
  @media (max-width: 720px) and (pointer: coarse) {
    .cl-name::after { content: ""; position: absolute; inset: 0; }
    .cl-name:focus-visible { outline-offset: -2px; }
  }
