/* Map — the app's own parts.
   Header, card, bar, gutter, one left edge, the refusal, the empty state, the
   list, the section: os-app.css. ⛔ Do not redraw them.

   Scope is `.osApp.osMap` — the app root, which the pane always carries — so
   the app draws the same on the Work OS home and in a thread.

   ⚡ Clay, through tokens only. The world's tokens (--cream, --cream2, --lav2,
   --clay-mint, --clay-peach, --clay, --lift…) are declared by work-clay.css;
   every use carries a token fallback so the same sheet still draws on a
   surface the skin has not reached. ⛔ No hex, no prefers-color-scheme block,
   no font import — one design, and dark is closed. The only literal colours on
   this screen are the bucket swatches, and they arrive INSIDE the artifact as
   data (the server's scale), painted verbatim, never declared here.

   Four things here exist in no other app and are why this sheet exists:
     the LENS CHIPS (.osMapLenses / .osMapLens) — eleven views, three of which
       refuse today and wear that state instead of hiding;
     the STAGE (.osMapStage / .osMapPic / .osMapNav) — the server's picture,
       verbatim, with a viewport that can move;
     the TIME SCRUBBER (.osMapTime) — one range, a tick per year, an
       unmeasured year visibly a year;
     the ABSENCE LEGEND (.osMapLg.abs) — hatch swatches drawn from the
       artifact's own pattern defs, each with its reason in words. */

/* ⛔ The crumb is one word and never two lines (measured on Registry at 390). */
.osApp.osMap .rhTop .crumb{white-space:nowrap;flex:none}
/* the subject line takes programmatic focus when the pane opens so a screen
   reader announces it; it is not a control and draws no ring for that */
.osApp.osMap .rhName:focus{outline:none}

/* ═══ THE LENS CHIPS ═════════════════════════════════════════════════════
   A row of pills, the chosen one filled. Each chip is a 44px target with a
   glyph and a word. The row scrolls at a narrow width — it never clips
   (os-app.css tabs rule, same reason). A REFUSING lens keeps its chip and
   wears a hatch: the same visual channel the map uses for "no number", so a
   person who has read one legend has read both. */
.osApp.osMap .osMapLenses{
  display:flex;gap:6px;padding:2px 0 12px;overflow-x:auto;scrollbar-width:thin;
  /* the row fades at its right edge, so a chip cut by the card reads as
     "more to the right" rather than as the end of the list */
  -webkit-mask-image:linear-gradient(90deg,currentColor calc(100% - 36px),transparent);
  mask-image:linear-gradient(90deg,currentColor calc(100% - 36px),transparent)}
.osApp.osMap .osMapLens{
  flex:0 0 auto;display:inline-flex;align-items:center;gap:7px;min-height:44px;padding:0 15px 0 12px;
  border:1px solid var(--line);border-radius:var(--r-pill,999px);background:var(--cream,var(--surf));
  color:var(--muted);font:600 12.5px/1 var(--body);cursor:pointer;box-shadow:var(--lift,none);
  transition:background .16s,color .16s,transform .16s cubic-bezier(.2,.8,.2,1)}
.osApp.osMap .osMapLens .g{display:inline-flex;width:16px;height:16px;flex:none}
.osApp.osMap .osMapLens .g svg{width:16px;height:16px}
.osApp.osMap .osMapLens:hover{color:var(--ink);border-color:var(--line2);transform:translateY(-1px)}
.osApp.osMap .osMapLens.on{
  background:var(--fill);color:var(--onfill);border-color:transparent;box-shadow:var(--clay,none)}
.osApp.osMap .osMapLens:focus-visible{outline:2px solid var(--violet);outline-offset:2px}
.osApp.osMap .osMapLens.on:focus-visible{outline-color:var(--ink)}
/* the refusing chip: hatched ground, a dashed edge, the word "refused" as a
   small mono tag — word AND pattern, never colour alone */
.osApp.osMap .osMapLens.refused{
  border-style:dashed;color:var(--muted);
  background:repeating-linear-gradient(135deg,var(--cream,var(--surf)) 0 5px,var(--surf2) 5px 6px)}
.osApp.osMap .osMapLens.refused .r{
  font:600 9.5px/1 var(--osMono);letter-spacing:.06em;text-transform:uppercase;
  padding:3px 6px;border-radius:999px;background:var(--surf2);color:var(--ink)}
.osApp.osMap .osMapLens.refused.on{background:var(--ink);color:var(--cream,var(--panel));border-style:solid}
.osApp.osMap .osMapLens.refused.on .r{background:var(--cream,var(--panel));color:var(--ink)}

/* ── the controls strip: metric · grain · years · basemap ──────────────── */
.osApp.osMap .osMapCtl{
  display:flex;flex-wrap:wrap;gap:10px 18px;align-items:flex-end;padding:0 0 14px;
  border-bottom:1px solid var(--line);margin-bottom:14px}
.osApp.osMap .osMapField{display:flex;flex-direction:column;gap:5px;min-width:0}
.osApp.osMap .osMapField>span:first-child{
  font:700 9.5px/1 var(--body);letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.osApp.osMap .osMapField select,.osApp.osMap .osMapField input:not([type=range]),.osApp.osMap .osMapYear input{
  min-height:36px;padding:6px 12px;border:1px solid var(--line);border-radius:var(--r-s,12px);
  background:var(--cream,var(--surf));color:var(--ink);font:500 13px/1.3 var(--body);max-width:100%}
.osApp.osMap .osMapField select:focus-visible,.osApp.osMap .osMapField input:focus-visible,.osApp.osMap .osMapYear input:focus-visible{
  outline:2px solid var(--violet);outline-offset:1px}
.osApp.osMap .osMapField select[disabled]{opacity:.55}
.osApp.osMap .osMapYears{display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap;min-height:36px}
.osApp.osMap .osMapYear{display:inline-flex;align-items:center;gap:6px;font:500 12px var(--body);color:var(--muted)}
.osApp.osMap .osMapYear input{width:5.4em;padding:6px 8px}
.osApp.osMap .osMapBm{display:inline-flex;gap:4px;flex-wrap:wrap}
.osApp.osMap .osMapHint{font:400 11.5px/1.4 var(--body);color:var(--muted);max-width:34ch}
/* the small verb: a 36px pill, filled when it is the current choice */
.osApp.osMap .osMapMini{
  min-height:36px;min-width:36px;padding:6px 12px;border:1px solid var(--line);border-radius:var(--r-pill,999px);
  background:var(--cream,var(--surf));color:var(--ink);font:600 12px/1.2 var(--body);cursor:pointer}
.osApp.osMap .osMapMini:hover{border-color:var(--line2);background:var(--cream2,var(--surf2))}
.osApp.osMap .osMapMini.on,.osApp.osMap .osMapMini.primary{background:var(--fill);color:var(--onfill);border-color:transparent}
.osApp.osMap .osMapMini[disabled]{opacity:.45;cursor:default}
.osApp.osMap .osMapMini:focus-visible{outline:2px solid var(--violet);outline-offset:2px}
.osApp.osMap .osMapLink{
  border:0;background:none;padding:0;font:inherit;color:var(--violet);text-decoration:underline;
  text-underline-offset:2px;cursor:pointer;min-height:24px;text-align:left}
.osApp.osMap .osMapLink:focus-visible{outline:2px solid var(--violet);outline-offset:2px;border-radius:4px}

/* ── the viewport bar: the shared bar, a label in front of the field ────── */
.osApp.osMap .osAppBar{padding:0 0 6px}
.osApp.osMap .osMapVpLab{
  flex:none;font:700 9.5px/1 var(--body);letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.osApp.osMap .osAppBar input{font:500 13.5px/1.4 var(--osMono);max-width:34em}
.osApp.osMap .osMapCaveat{margin:6px 0 0;max-width:68ch;font:400 11.5px/1.55 var(--body);color:var(--muted)}
.osApp.osMap .osMapCaveat b{color:var(--ink);font-weight:700}
.osApp.osMap [data-part="bar"] .osMapCaveat{margin:0 0 12px}

/* ═══ THE STAGE ══════════════════════════════════════════════════════════
   The picture on the left, the side on the right; the side becomes a row
   under the picture when the column is narrow. */
.osApp.osMap .osMapGrid{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:18px;align-items:start}
.osApp.osMap .osMapStage{min-width:0;position:relative}
.osApp.osMap .osMapStage[aria-busy="true"] .osMapPic{opacity:.55;transition:opacity .2s}
.osApp.osMap .osMapPic{
  border-radius:var(--r-s,12px);overflow:hidden;background:var(--cream2,var(--surf));box-shadow:var(--lift,none);
  /* the tiled wrapper's own ground, through our token — the artifact reads
     --bc-map-ground and falls back to its own literal without it */
  --bc-map-ground:var(--cream2,var(--surf));color:var(--ink)}
.osApp.osMap .osMapPic .bc-map{margin:0 auto}
.osApp.osMap .osMapPic svg{display:block}
/* ⛔ THE OVERLAY MUST TAKE THE CLICK. The tiled wrapper sets
   `pointer-events:none` on the overlay div so the tiles beneath stay
   draggable-looking, and the SVG paths INHERIT it — so on the public page a
   territory could not be pressed at all under a basemap (measured 2026-09-08).
   The path is the target; only the path. */
.osApp.osMap .osMapPic .bc-map-area{pointer-events:auto;cursor:pointer;transition:stroke-opacity .12s}
.osApp.osMap .osMapPic .bc-map-area:hover{stroke:var(--ink);stroke-opacity:.85;stroke-width:1.6}
/* a selected territory: a heavier violet edge — weight and hue, on the STROKE
   only, never on the fill that carries the value */
.osApp.osMap .osMapPic .bc-map-area.osMapSel{stroke:var(--violet);stroke-opacity:1;stroke-width:2.4}
/* the pan/zoom cluster: six 44px targets in the picture's corner, cream on
   the map so they read on tiles and on the plain ground alike */
.osApp.osMap .osMapNav{
  position:absolute;top:10px;right:10px;display:grid;grid-template-columns:repeat(3,44px);gap:4px;
  padding:4px;border-radius:var(--r-s,12px);background:var(--glass,var(--panel));box-shadow:var(--lift,none)}
.osApp.osMap .osMapNav button{
  width:44px;height:44px;border:0;border-radius:9px;background:var(--cream,var(--surf));color:var(--ink);
  font:700 16px/1 var(--body);cursor:pointer}
.osApp.osMap .osMapNav button:hover{background:var(--lav2,var(--surf2))}
.osApp.osMap .osMapNav button:focus-visible{outline:2px solid var(--violet);outline-offset:1px}
.osApp.osMap .osMapNav [data-pan="u"]{grid-column:2}
.osApp.osMap .osMapNav [data-pan="l"]{grid-column:1;grid-row:2}
.osApp.osMap .osMapNav [data-pan="r"]{grid-column:3;grid-row:2}
.osApp.osMap .osMapNav [data-pan="d"]{grid-column:2;grid-row:3}
.osApp.osMap .osMapNav [data-zoom="in"]{grid-column:3;grid-row:1}
.osApp.osMap .osMapNav [data-zoom="out"]{grid-column:3;grid-row:3}
.osApp.osMap .osMapRefused{display:flex;flex-direction:column;gap:12px;max-width:72ch}
.osApp.osMap .osMapWhy{margin:8px 0 0;font:400 12.5px/1.5 var(--body);color:var(--ink)}
.osApp.osMap .osMapFix{margin:8px 0 0;font:400 12.5px/1.5 var(--body);color:var(--ink)}
.osApp.osMap .osMapFix b{display:inline;font:700 12px var(--body);color:var(--mint);margin:0}
/* the refusing lens's metric rows: a tick or a stop, the metric, the verb */
.osApp.osMap .osMapMs{
  display:grid;grid-template-columns:1.4em minmax(0,1fr) auto;gap:10px;align-items:center;
  padding:8px 0;border-bottom:1px solid var(--line);font:500 13px/1.35 var(--body);color:var(--ink)}
.osApp.osMap .osMapMs .w{font:700 12px var(--osMono);color:var(--amber);text-align:center}
.osApp.osMap .osMapMs.ok .w{color:var(--mint)}
.osApp.osMap .osMapMs .v{font:400 12px var(--osMono);color:var(--muted);text-align:right}

/* ═══ THE TIME SCRUBBER ══════════════════════════════════════════════════
   One row under the picture: the year, the range, the ticks, the frame's
   sentence. A measured tick is solid ink; an unmeasured tick is a hollow
   square — a year with nothing in it is still a year on the strip. */
.osApp.osMap .osMapTime{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:10px;padding:8px 12px;
  border-radius:var(--r-s,12px);background:var(--cream,var(--surf));box-shadow:var(--lift,none)}
.osApp.osMap .osMapYearNow{font:800 16px/1 var(--disp,var(--osDisp));color:var(--ink);min-width:3em;text-align:center}
.osApp.osMap .osMapRange{flex:1 1 160px;min-width:120px;height:44px;accent-color:var(--violet);margin:0}
.osApp.osMap .osMapRange:focus-visible{outline:2px solid var(--violet);outline-offset:2px;border-radius:6px}
.osApp.osMap .osMapTicks{display:inline-flex;gap:3px;align-items:center}
.osApp.osMap .osMapTicks i{display:block;width:8px;height:8px;border-radius:2px;border:1.5px solid var(--ink);background:transparent;box-sizing:border-box}
.osApp.osMap .osMapTicks i.measured{background:var(--ink)}
.osApp.osMap .osMapTicks i.now{outline:2px solid var(--violet);outline-offset:1px}
.osApp.osMap .osMapFrameState{font:600 12px/1.3 var(--body);color:var(--ink)}
.osApp.osMap .osMapFrameState.abs{color:var(--amber)}

/* ═══ THE SIDE: legend · absences · caveats · territories · selection ════ */
.osApp.osMap .osMapSide{min-width:0}
.osApp.osMap .osMapSide .osAppSec:first-child{border-top:0;padding-top:0;margin-top:0}
.osApp.osMap .osMapSide h4{
  margin:12px 0 6px;font:700 9.5px/1 var(--body);letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.osApp.osMap .osMapLgs{display:flex;flex-direction:column;gap:5px}
.osApp.osMap .osMapLg{display:flex;align-items:center;gap:9px;font:500 12.5px/1.35 var(--body);color:var(--ink)}
.osApp.osMap .osMapLg i{display:block;flex:none;width:22px;height:16px;border-radius:3px;border:1px solid var(--line2)}
.osApp.osMap .osMapLg.abs{align-items:flex-start;color:var(--muted);font-weight:400}
.osApp.osMap .osMapLg.abs svg{flex:none;margin-top:1px;color:var(--ink)}
.osApp.osMap .osMapLg.abs b{color:var(--ink);font-weight:700}
/* the bubble key: nested rings at real radii, the value beside each */
.osApp.osMap .osMapBubbles{display:flex;align-items:flex-end;gap:14px;margin:8px 0 0}
.osApp.osMap .osMapBubbles span{display:inline-flex;flex-direction:column;align-items:center;gap:4px;font:500 11px var(--osMono);color:var(--muted)}
.osApp.osMap .osMapBubbles i{display:block;border-radius:50%;border:1.5px solid var(--ink);background:var(--clay-mint,var(--surf2))}
.osApp.osMap .osMapCaveats{margin:0;padding:0 0 0 1.1em;font:400 12px/1.5 var(--body);color:var(--muted)}
.osApp.osMap .osMapCaveats li{margin:0 0 6px}
.osApp.osMap .osMapCaveats li b{color:var(--ink);font-weight:700}
.osApp.osMap .osMapCaveats li.material{color:var(--ink)}
.osApp.osMap .osMapCaveats li.material::marker{color:var(--amber)}
.osApp.osMap .osMapCaveats .sev{
  display:inline-block;margin-left:4px;padding:1px 7px;border-radius:999px;background:var(--surf2);
  font:600 10px/1.5 var(--osMono);color:var(--muted)}
.osApp.osMap .osMapCaveats li.material .sev{background:var(--clay-peach,var(--surf2));color:var(--amber)}
.osApp.osMap .osMapCaveats i{font-style:normal;color:var(--muted)}
/* territories: the shared list, a value on the right, an absent one muted with its word */
.osApp.osMap .osAppList .row.osMapRow{
  padding:8px 12px 8px 14px;min-height:44px;background:var(--cream,transparent);border:0;
  box-shadow:var(--lift,none);border-radius:var(--r-s,12px)}
.osApp.osMap .osAppList .row.osMapRow:hover{background:var(--cream2,var(--surf))}
.osApp.osMap .osAppList .row.osMapRow:focus-visible{outline:2px solid var(--violet);outline-offset:2px}
.osApp.osMap .osAppList .row.osMapRow.on{box-shadow:0 0 0 2px var(--violet) inset,var(--lift,none)}
.osApp.osMap .osAppList .row.osMapRow .t{font:600 13px/1.3 var(--body);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.osApp.osMap .osAppList .row.osMapRow .t i{font-style:normal;color:var(--amber)}
.osApp.osMap .osAppList .row.osMapRow .n{font:600 12.5px var(--osMono);white-space:nowrap}
.osApp.osMap .osAppList .row.osMapRow .n i{font-style:normal;font-weight:400;color:var(--muted);font-size:11px}
.osApp.osMap .osAppList .row.osMapRow.abs .n{color:var(--amber);font:500 11.5px var(--body)}
.osApp.osMap .osMapSide .osMapLink{margin-top:8px;font-size:12px}
/* the selection: chips carrying the number seen, a form, two verbs */
.osApp.osMap .osMapChips{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:10px}
.osApp.osMap .osMapChip{
  display:inline-flex;align-items:center;gap:8px;padding:4px 4px 4px 11px;border-radius:999px;
  background:var(--lav2,var(--surf2));color:var(--ink);font:600 12px/1.3 var(--body)}
.osApp.osMap .osMapChip .val{font:500 11px var(--osMono);color:var(--muted)}
.osApp.osMap .osMapChip button{
  width:24px;height:24px;border:0;border-radius:50%;background:var(--cream,var(--panel));color:var(--ink);
  font:700 13px/1 var(--body);cursor:pointer}
.osApp.osMap .osMapChip button:hover{background:var(--fill);color:var(--onfill)}
.osApp.osMap .osMapChip button:focus-visible{outline:2px solid var(--violet);outline-offset:1px}
.osApp.osMap .osMapSelForm{display:flex;flex-direction:column;gap:10px}
.osApp.osMap .osMapSelForm .osMapField input{min-height:36px}
.osApp.osMap .osMapSelActs{display:flex;gap:8px;flex-wrap:wrap}

/* ── "About this map" — under the card, folded ─────────────────────────── */
.osApp.osMap .osMapAbout{margin:14px 19px 0;color:var(--muted)}
.osApp.osMap .osMapAbout summary{
  cursor:pointer;list-style:none;display:inline-flex;align-items:center;gap:7px;min-height:24px;
  font:700 10px/1 var(--body);letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.osApp.osMap .osMapAbout summary::-webkit-details-marker{display:none}
.osApp.osMap .osMapAbout summary::before{content:'›';font-size:13px;transition:transform .15s}
.osApp.osMap .osMapAbout[open] summary::before{transform:rotate(90deg)}
.osApp.osMap .osMapAbout summary:hover{color:var(--ink)}
.osApp.osMap .osMapAbout summary:focus-visible{outline:2px solid var(--violet);outline-offset:3px;border-radius:4px}
.osApp.osMap .osMapAbout p{margin:9px 0 0;max-width:72ch;font:400 12px/1.6 var(--body)}
.osApp.osMap .osMapAbout p b{color:var(--ink);font-weight:700}
.osApp.osMap .osMapDefs{position:absolute;width:0;height:0;overflow:hidden}

/* ═══ FINDING A PLACE (SPEC-MAP-PLATFORM §7) ═══════════════════════════════
   The door into the map, so it sits above the lens row: a person who knows
   where they want to go should not have to choose a lens first. */
.osApp.osMap .osMapSearch{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:0 0 4px}
.osApp.osMap .osMapSearchLab{
  font:700 10.5px/1 var(--body);letter-spacing:.10em;text-transform:uppercase;color:var(--muted)}
.osApp.osMap .osMapSearch input{
  flex:1 1 22em;min-width:0;min-height:40px;padding:8px 12px;
  border:1px solid var(--line);border-radius:var(--r-s,12px);
  background:var(--panel,var(--surf));color:var(--ink);font:500 14px/1.35 var(--body)}
.osApp.osMap .osMapSearch input:focus-visible{outline:2px solid var(--violet);outline-offset:2px;border-color:var(--line2)}
.osApp.osMap .osMapSearch input::-webkit-search-cancel-button{display:none}

/* the results: a real list, not an overlay — an overlay hides the map the
   person is about to move, and on a phone it covers the whole thing */
.osApp.osMap .osMapHits{
  list-style:none;margin:0 0 6px;padding:6px;display:flex;flex-direction:column;gap:2px;
  max-height:240px;overflow:auto;
  border:1px solid var(--line);border-radius:var(--r-s,12px);background:var(--panel,var(--surf))}
.osApp.osMap .osMapHit{
  display:grid;grid-template-columns:8.5em 1fr auto;align-items:baseline;gap:10px;width:100%;
  min-height:40px;padding:7px 10px;border:0;border-radius:9px;background:none;
  color:var(--ink);font:500 13px/1.35 var(--body);text-align:left;cursor:pointer}
.osApp.osMap button.osMapHit:hover{background:var(--cream2,var(--surf2))}
.osApp.osMap button.osMapHit:focus-visible{outline:2px solid var(--violet);outline-offset:-2px}
.osApp.osMap .osMapHit .k{
  font:700 10.5px/1.5 var(--body);letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
.osApp.osMap .osMapHit .l{font-weight:600;overflow-wrap:anywhere}
.osApp.osMap .osMapHit .s{font:400 12px/1.4 var(--body);color:var(--muted);justify-self:start}
/* ⛔ An unmappable row STAYS, dimmed and unpressable, with its reason. Dropping
   it would make the count lie; flying to it would make the map lie. */
.osApp.osMap .osMapHit.off{cursor:default;opacity:.72}
.osApp.osMap .osMapHit .s.abs{color:var(--muted);font-style:italic}
.osApp.osMap .osMapHitNote{padding:8px 10px;font:400 12.5px/1.5 var(--body);color:var(--muted)}
.osApp.osMap .osMapHitNote.abs{font-style:italic}
.osApp.osMap .osMapHitCount{margin:0 0 6px;font:400 11.5px/1.5 var(--body);color:var(--muted)}
.osApp.osMap .osMapFound{
  margin:0 0 8px;font:500 12.5px/1.5 var(--body);color:var(--ink)}
.osApp.osMap .osMapFound i{font-style:normal;color:var(--muted)}

/* ═══ THE PALETTE PICKER (SPEC-MAP-PLATFORM §6) ════════════════════════════
   ⛔ Real bands of the real ramp. A person choosing a palette is choosing a
   picture, and a name is not one. */
.osApp.osMap .osMapPals{display:inline-flex;gap:6px;flex-wrap:wrap}
.osApp.osMap .osMapPal{
  display:inline-flex;flex-direction:column;gap:4px;align-items:flex-start;
  min-height:44px;padding:5px 7px;border:1px solid var(--line);border-radius:9px;
  background:var(--cream,var(--surf));cursor:pointer}
.osApp.osMap .osMapPal:hover{border-color:var(--line2)}
.osApp.osMap .osMapPal.on{border-color:var(--fill);box-shadow:0 0 0 1px var(--fill) inset}
.osApp.osMap .osMapPal:focus-visible{outline:2px solid var(--violet);outline-offset:2px}
.osApp.osMap .osMapPal .sw{display:inline-flex;border-radius:3px;overflow:hidden}
.osApp.osMap .osMapPal .sw i{width:11px;height:12px;display:block}
.osApp.osMap .osMapPal .l{font:600 11px/1 var(--body);color:var(--muted)}
.osApp.osMap .osMapPal.on .l{color:var(--ink)}

/* ── narrow columns: the side goes under the picture; controls stack ───── */
@media (max-width:1000px){
  .osApp.osMap .osMapGrid{grid-template-columns:1fr}
}
@media (max-width:640px){
  .osApp.osMap .osMapCtl{gap:10px 12px}
  .osApp.osMap .osMapSearchLab{flex:1 0 100%}
  .osApp.osMap .osMapHit{grid-template-columns:1fr;gap:2px}
  .osApp.osMap .osMapHits{max-height:200px}
  .osApp.osMap .osMapField{flex:1 1 46%}
  .osApp.osMap .osAppBar{flex-wrap:wrap}
  .osApp.osMap .osMapVpLab{flex:1 0 100%}
  .osApp.osMap .osMapNav{top:6px;right:6px;grid-template-columns:repeat(3,40px)}
  .osApp.osMap .osMapNav button{width:40px;height:40px}
  .osApp.osMap .osMapAbout{margin:12px 4px 0}
  .osApp.osMap .osMapLens{padding:0 12px 0 10px}
}
@media (max-width:420px){
  .osApp.osMap .osMapField{flex:1 1 100%}
  .osApp.osMap .osMapTime{padding:8px}
  .osApp.osMap .osMapYearNow{min-width:2.6em}
}
@media (prefers-reduced-motion:reduce){
  .osApp.osMap .osMapLens,.osApp.osMap .osMapPic .bc-map-area,.osApp.osMap .osMapAbout summary::before,
  .osApp.osMap .osMapStage[aria-busy="true"] .osMapPic{transition:none}
  .osApp.osMap .osMapLens:hover{transform:none}
}

/* ═══ THE MOVING MAP (SPEC-MAP-PLATFORM §5) ════════════════════════════════
   The GL canvas sits OVER the server picture rather than replacing it, so a
   library that fails to load leaves a complete answer showing — captions,
   exclusions and scale bar included — instead of an empty box. */
.osApp.osMap .osMapStage{position:relative}
.osApp.osMap .osMapGl{
  position:absolute;inset:0;border-radius:var(--r-s,12px);overflow:hidden;z-index:1;
  /* ⛔ TRANSPARENT UNTIL IT HAS PAINTED. A canvas that exists is not a canvas
     that is ready: measured 2026-09-09, a half-drawn GL map (polygons yes,
     basemap tiles no) sat on top of a complete server picture and hid it. */
  opacity:0;pointer-events:none;transition:opacity .18s}
.osApp.osMap .osMapGl.painted{opacity:1;pointer-events:auto}
/* ⛔ The still picture stays in the DOM under the canvas: it is the fallback,
   and it is what a browser with no WebGL — a blocklisted driver, an enterprise
   policy, a headless run — actually shows. It is a complete answer: captions,
   exclusions, scale bar. */
.osApp.osMap .osMapPic{transition:opacity .15s}
/* ⛔ Hidden by the CANVAS having painted, never by our intention to mount one.
   `.painted` is set on the GL host by maplibre's own `idle` event. */
.osApp.osMap .osMapStage:has(.osMapGl.painted) .osMapPic{visibility:hidden}
@media (prefers-reduced-motion:reduce){ .osApp.osMap .osMapGl{transition:none} }
.osApp.osMap .osMapGl .maplibregl-ctrl-group{
  border-radius:10px;box-shadow:var(--lift,0 2px 8px rgba(0,0,0,.12));border:1px solid var(--line)}
.osApp.osMap .osMapGl .maplibregl-ctrl-group button{width:34px;height:34px}
.osApp.osMap .osMapGl canvas:focus-visible{outline:2px solid var(--violet);outline-offset:-2px}
/* the arrow cluster keeps its place ABOVE the canvas — a map that can only be
   dragged is a map some people cannot move at all */
.osApp.osMap .osMapNav{z-index:2}

/* ═══════════════════════════════════════════════════════════════════════════
   THE SHOWCASE (SPEC-MAP-PLATFORM §2 · BRIEF-MAP-LOOK 2026-09-10)

   Owner, 2026-09-09: *"user don't read, they want visuals and inspiration on
   map use cases, colourful ones, not just green and classic."*
   Owner, 2026-09-10: *"the look and feel ie on other main views and apps like
   this"* — the company home. *"less texts, more visuals please."*

   So the map is the GROUND and everything else floats on it, and the film
   strip under it is the app's table of contents.

   ⛔ THE PANE IS CLAY; ONLY THE MAP WEARS THE WORLD. A world is the colour of
      a PICTURE inside the clay app, the way a photograph in a document may be
      dark without the document having a dark mode. `--w-ground` reaches the
      STAGE (the canvas and its still fallback) and nothing else; `--w-accent`
      reaches the caption's swatch dot and nothing else. Every plate, the side
      drawer and every card is `--panel`/`--cream` in every world — there is
      no dark-chrome selector in this sheet and there must never be one again.
   ⛔ NO HEX. The tokens are work-clay.css's; a literal here would be a second
      palette that drifts the day the skin moves.
   ═══════════════════════════════════════════════════════════════════════════ */

.osApp.osMap .osMapShow{padding:0;overflow:hidden}
.osApp.osMap .osMapWrap{max-width:1400px}

/* ── the world: the map fills it, the chrome floats over it ─────────────── */
.osApp.osMap .osMapWorld{
  position:relative;
  /* the three the scene sets; the fallbacks are the workspace's own tokens,
     so a world that failed to load renders as the product rather than as nothing */
  --w-ground:var(--bg); --w-ink:var(--ink); --w-accent:var(--fill);
  /* ⛔ CLAY, ALWAYS. The wrapper used to wear the world's ground, and inside
     the cream shell a black rectangle with black panels read as a different
     product (measured in the owner's Safari, 2026-09-10). */
  background:var(--bg,var(--panel));
  /* ⛔ A FIXED HEIGHT, NOT A MINIMUM. Measured 2026-09-10: the side panel's own
     content stretched the grid row, so the map grew past the fold and the year
     scrubber — the control that makes the whole thing legible without reading —
     ended up below it. The drawer scrolls inside the world; the world does not
     grow to fit it. */
  height:clamp(440px,62vh,780px);
  display:grid;grid-template-columns:1fr}
.osApp.osMap .osMapWorld .osMapStage{
  position:relative;grid-column:1;min-height:inherit;border-radius:0}

/* ── the side: a DRAWER over the map's right edge, closed until ⓘ ──────────
   ⛔ Hidden on first paint (the `hidden` attribute in the shell); opened by
   the ⓘ beside Tune. It lies OVER the map — the map is never narrowed — as a
   cream plate with the workspace's own type. */
.osApp.osMap .osMapWorld .osMapSide{
  position:absolute;top:12px;right:12px;bottom:12px;width:min(320px,calc(100% - 24px));z-index:4;
  border:1px solid var(--line);border-radius:var(--r,22px);
  background:color-mix(in srgb, var(--panel) 96%, transparent);
  box-shadow:var(--lift-2,var(--lift,none));backdrop-filter:blur(12px) saturate(1.05);
  overflow:auto;padding:12px 14px 16px;color:var(--ink)}
.osApp.osMap .osMapWorld .osMapSide[hidden]{display:none}
.osApp.osMap .osMapSideHead{display:flex;align-items:center;justify-content:space-between;gap:8px;margin:0 0 6px}
.osApp.osMap .osMapSideHead h3{
  margin:0;font:600 12px/1.2 var(--mono,var(--osMono,ui-monospace,monospace));letter-spacing:.12em;
  text-transform:uppercase;color:var(--faint,var(--muted))}
.osApp.osMap .osMapSideClose{min-width:32px;min-height:32px;padding:0 9px;font-size:15px}
.osApp.osMap .osMapSide .osAppSec{border-top:1px solid var(--line);padding-top:10px;margin-top:10px}
.osApp.osMap .osMapSide .osAppSec:first-of-type{border-top:0;padding-top:0;margin-top:0}
.osApp.osMap .osMapSide .osAppSec>h3{
  font:600 11px/1.2 var(--mono,var(--osMono,ui-monospace,monospace));letter-spacing:.12em;
  text-transform:uppercase;color:var(--faint,var(--muted));margin:0 0 8px}
/* the territory row: name, number, and a BAR of the number — the same value,
   drawn as a length so the top five read without reading */
.osApp.osMap .osMapSide .osAppList .row.osMapRow{
  display:grid;grid-template-columns:minmax(0,1fr) auto;gap:2px 10px;align-items:center;
  padding:8px 12px;min-height:44px;border:0;border-radius:var(--r-s,12px);
  background:var(--cream,var(--panel));box-shadow:var(--lift,none)}
.osApp.osMap .osMapSide .osAppList .row.osMapRow .bar{
  grid-column:1/-1;display:block;height:5px;border-radius:var(--r-pill,999px);
  background:var(--lav,var(--surf2));overflow:hidden}
.osApp.osMap .osMapSide .osAppList .row.osMapRow .bar i{
  display:block;height:100%;border-radius:inherit;background:var(--fill)}
.osApp.osMap .osMapSide .osAppList .row.osMapRow.on{background:var(--lav,var(--surf2));box-shadow:0 0 0 2px var(--fill) inset,var(--lift,none)}
/* the caveats: every word the server sent, folded, the count on the summary */
.osApp.osMap .osMapCaveatsFold summary{
  cursor:pointer;list-style:none;display:inline-flex;align-items:center;gap:7px;min-height:24px;
  font:600 11px/1.2 var(--mono,var(--osMono,ui-monospace,monospace));letter-spacing:.12em;
  text-transform:uppercase;color:var(--faint,var(--muted))}
.osApp.osMap .osMapCaveatsFold summary::-webkit-details-marker{display:none}
.osApp.osMap .osMapCaveatsFold summary::before{content:'›';font-size:13px;transition:transform .15s}
.osApp.osMap .osMapCaveatsFold[open] summary::before{transform:rotate(90deg)}
.osApp.osMap .osMapCaveatsFold summary:hover{color:var(--ink)}
.osApp.osMap .osMapCaveatsFold summary:focus-visible{outline:2px solid var(--violet);outline-offset:3px;border-radius:4px}
.osApp.osMap .osMapCaveatsFold .osMapCaveats{margin-top:8px}

/* the overlay layer — every child gets its own pointer events back */
.osApp.osMap .osMapOver{
  position:absolute;left:0;top:0;bottom:0;right:0;display:flex;flex-direction:column;
  justify-content:space-between;padding:12px;pointer-events:none;z-index:3;gap:10px}
/* the chrome steps aside for the drawer so the legend never sits under the list */
.osApp.osMap .osMapWorld.sideOpen .osMapOver{right:344px}
.osApp.osMap .osMapOver>*{pointer-events:none}
.osApp.osMap .osMapOver button,
.osApp.osMap .osMapOver input,
.osApp.osMap .osMapOver select,
.osApp.osMap .osMapOver summary,
.osApp.osMap .osMapOver .osMapHits,
.osApp.osMap .osMapOver .osMapCapIn{pointer-events:auto}
.osApp.osMap .osMapTop{display:flex;gap:10px;align-items:flex-start;justify-content:space-between}
.osApp.osMap .osMapTopL{flex:1 1 26em;max-width:34em;min-width:0;display:grid;gap:8px}
.osApp.osMap .osMapTopR{flex:0 0 auto;display:flex;justify-content:flex-end}
.osApp.osMap .osMapMid{flex:1 1 auto;min-height:0}
.osApp.osMap .osMapBot{display:flex;gap:10px;align-items:flex-end;justify-content:space-between;flex-wrap:wrap}
/* ⛔ The legend does not shrink. Measured 2026-09-10: flexed against the time
   control it collapsed to a column two words wide — "up to 830 / companies" —
   which is the one thing on a map that has to be read at a glance. */
.osApp.osMap .osMapBotL{flex:0 0 auto;min-width:14em}
.osApp.osMap .osMapBotR{flex:0 1 auto;min-width:0}
/* ⛔ The time control gets a real floor. As `flex:1 1 auto; min-width:0` it
   shrank under the legend and the source line and the sentence under the slider
   broke over four lines — measured twice, on 4902 and again on 4896. It wraps
   to its own row rather than collapsing. */
.osApp.osMap .osMapTimeSlot{flex:1 1 24em;justify-content:center;min-width:min(24em,100%)}
/* ⛔ The legend must not eat the map. It scrolls inside itself instead. */
.osApp.osMap .osMapOver [data-part="legend"] .osMapLegend{max-height:min(38vh,320px)}

/* ── THE PLATES: cream in every world ────────────────────────────────────────
   ⛔ Floating chrome is a PLATE, not a tint: text over a map with no plate is
   unreadable the moment the map moves under it — and a `color-mix` wash over a
   busy street basemap lost the legend (brief §1.4). So: `--panel` at ≈.96, a
   1 px `--line` edge, `--r-s`, `--lift`, `--ink` type — the same plate the
   company home draws its cards on, in the night world and the meadow alike. */
.osApp.osMap .osMapOver .osMapSearch,
.osApp.osMap .osMapOver .osMapCtlShut,
.osApp.osMap .osMapOver .osMapCtl,
.osApp.osMap .osMapCapIn,
.osApp.osMap .osMapOver [data-part="legend"]>*,
.osApp.osMap .osMapOver [data-part="foot"]{
  background:color-mix(in srgb, var(--panel) 96%, transparent);
  border:1px solid var(--line);border-radius:var(--r-s,12px);color:var(--ink);
  box-shadow:var(--lift,none);
  backdrop-filter:blur(10px) saturate(1.05)}
.osApp.osMap .osMapOver .osMapSearch{padding:8px 10px;margin:0}
.osApp.osMap .osMapOver .osMapCtlShut{padding:7px 9px;display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.osApp.osMap .osMapOver .osMapCtl{padding:12px;max-width:44em}
.osApp.osMap .osMapOver [data-part="foot"]{
  padding:6px 10px;font:400 11px/1.45 var(--body);color:var(--muted);max-width:30em;flex:0 1 auto;min-width:0}
/* an empty plate is no plate — a sample scene has no source line, and the
   padded border drew a small white pill in the corner (measured 2026-09-10) */
.osApp.osMap .osMapOver [data-part="foot"]:empty,
.osApp.osMap .osMapOver [data-part="legend"]:empty{display:none}
.osApp.osMap .osMapOver [data-part="legend"]{max-width:19em;min-width:14em}
.osApp.osMap .osMapOver [data-part="legend"] .osMapLegend{padding:10px 12px;margin:0;max-height:44vh;overflow:auto}
/* the ⓘ: the same 36 px pill as Tune, filled while the drawer is open */
.osApp.osMap .osMapInfo{font-size:15px;line-height:1;padding:6px 10px;min-width:36px}

/* ── the caption: the ONE piece of prose, twelve words, in the top-left ──── */
.osApp.osMap .osMapCap{display:block}
.osApp.osMap .osMapCapIn{
  padding:12px 14px;max-width:30em;display:grid;gap:4px}
.osApp.osMap .osMapCapIn b{
  display:flex;align-items:center;gap:8px;font:800 17px/1.2 var(--disp,var(--body));color:var(--ink)}
/* the world's swatch: a 10 px dot in the world's accent — the world is named
   by colour, never by a dark background */
.osApp.osMap .osMapCapIn b .sw{
  flex:none;width:10px;height:10px;border-radius:50%;background:var(--w-accent);
  box-shadow:0 0 0 2px var(--panel),0 0 0 3px var(--line)}
.osApp.osMap .osMapCapIn span{font:500 13.5px/1.5 var(--body);color:var(--ink)}
.osApp.osMap .osMapCapIn i{font:600 11px/1.4 var(--body);font-style:normal;color:var(--muted)}
/* ⛔ The stamp, not a paragraph: the sample scenes wear this and say nothing
   else. Peach clay and amber ink — the workspace's own warning pair. */
.osApp.osMap .osMapStamp,.osApp.osMap .osMapCard .st{
  justify-self:start;padding:2px 7px;border-radius:var(--r-pill,999px);
  border:1px solid var(--clay-peach,var(--line2));color:var(--amber);background:var(--clay-peach,var(--surf2));
  font:800 9.5px/1.5 var(--mono,var(--osMono,ui-monospace,monospace));letter-spacing:.12em}

/* ── the film strip: the table of contents ─────────────────────────────── */
.osApp.osMap .osMapStrip{border-top:1px solid var(--line);background:var(--bg,var(--panel));padding:12px 14px 16px}
.osApp.osMap .osMapStripHead{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:0 2px 10px}
/* `AINAS · 24` — the same small-caps mono as `LIETOTNES · 15` on the home */
.osApp.osMap .osMapStripH{
  margin:0;font:600 13px/1.2 var(--mono,var(--osMono,ui-monospace,monospace));letter-spacing:.14em;
  text-transform:uppercase;color:var(--faint,var(--muted))}
.osApp.osMap .osMapStripH .c{font-weight:500;font-size:11px;letter-spacing:.06em}
.osApp.osMap .osMapStripTgl{min-height:30px;padding:4px 10px;font-size:11px;color:var(--muted)}
.osApp.osMap .osMapGroups{display:flex;gap:22px;overflow-x:auto;padding:4px 2px 8px;scroll-snap-type:x proximity}
.osApp.osMap .osMapGroup{flex:0 0 auto;scroll-snap-align:start}
.osApp.osMap .osMapGroup h3{
  margin:0 0 8px;font:600 10px/1 var(--mono,var(--osMono,ui-monospace,monospace));letter-spacing:.12em;
  text-transform:uppercase;color:var(--faint,var(--muted))}
.osApp.osMap .osMapCards{display:flex;gap:10px}

/* ⚡ THE APP CARD. The same plate as the company home's LIETOTNES cards —
   cream, --r-s, --lift, no border — with the illustration as a 56 px rounded
   thumbnail on the left, a bold name, one muted line (the group) and one small
   status word. ⛔ The world's colours live INSIDE the thumbnail; the plate is
   clay in every world. Selected = lavender tint + a 2 px --fill inset ring,
   exactly like the selected rail item. */
.osApp.osMap .osMapCard{
  flex:0 0 auto;width:228px;display:grid;grid-template-columns:56px minmax(0,1fr);gap:10px;align-items:center;
  padding:8px 10px 8px 8px;border:0;border-radius:var(--r-s,12px);cursor:pointer;
  background:var(--cream,var(--panel));color:var(--ink);text-align:left;box-shadow:var(--lift,none);
  transition:transform .14s ease, box-shadow .14s ease, background .14s ease}
.osApp.osMap .osMapCard:hover{transform:translateY(-2px);box-shadow:var(--lift-2,var(--lift,none))}
.osApp.osMap .osMapCard.on{background:var(--lav,var(--surf2));box-shadow:0 0 0 2px var(--fill) inset,var(--lift,none)}
.osApp.osMap .osMapCard:focus-visible{outline:2px solid var(--violet);outline-offset:2px}
.osApp.osMap .osMapCard .th{
  position:relative;display:flex;width:56px;height:56px;border-radius:10px;overflow:hidden;
  background:var(--w-ground);box-shadow:inset 0 0 0 1px var(--line)}
.osApp.osMap .osMapCard .th i{flex:1;display:block}
.osApp.osMap .osMapCard .th img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;
  border-radius:inherit;opacity:.92;transition:opacity .14s ease}
.osApp.osMap .osMapCard:hover .th img,
.osApp.osMap .osMapCard.on .th img{opacity:1}
.osApp.osMap .osMapCard .tx{display:grid;gap:2px;min-width:0;justify-items:start}
.osApp.osMap .osMapCard .t{
  font:700 13px/1.25 var(--body);color:var(--ink);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
.osApp.osMap .osMapCard .g{
  font:500 11.5px/1.3 var(--body);color:var(--muted);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
/* the status word: SAMPLE keeps the peach stamp; a live scene says so in the
   quiet mono the home uses for `ieslēgts` */
.osApp.osMap .osMapCard .st{margin-top:2px}
.osApp.osMap .osMapCard .st.live{
  border:0;padding:0;background:none;color:var(--mint);
  font:600 10px/1.5 var(--mono,var(--osMono,ui-monospace,monospace));letter-spacing:.08em;text-transform:uppercase}

@media (max-width:1000px){
  .osApp.osMap .osMapWorld{height:clamp(360px,52vh,560px)}
  .osApp.osMap .osMapWorld.sideOpen .osMapOver{right:0}
  .osApp.osMap .osMapWorld .osMapSide{top:8px;right:8px;bottom:8px;width:calc(100% - 16px)}
}
@media (max-width:640px){
  .osApp.osMap .osMapCard{width:196px;grid-template-columns:48px minmax(0,1fr)}
  .osApp.osMap .osMapCard .th{width:48px;height:48px}
  .osApp.osMap .osMapOver{padding:8px;gap:8px}
  .osApp.osMap .osMapCapIn{max-width:100%}
}
@media (prefers-reduced-motion:reduce){
  .osApp.osMap .osMapCard{transition:none}
  .osApp.osMap .osMapCard:hover{transform:none}
  .osApp.osMap .osMapCard .th img{transition:none}
  .osApp.osMap .osMapCaveatsFold summary::before{transition:none}
}

/* ── the floating legend: a plate the size of a hand ───────────────────────
   cuts + the bubble key, nothing else; the reasoning one press away */
.osApp.osMap .osMapLegend h3{
  margin:0 0 8px;font:600 10px/1 var(--mono,var(--osMono,ui-monospace,monospace));letter-spacing:.12em;
  text-transform:uppercase;color:var(--faint,var(--muted))}
.osApp.osMap .osMapLegend h4{
  margin:10px 0 6px;font:600 9.5px/1 var(--mono,var(--osMono,ui-monospace,monospace));letter-spacing:.10em;
  text-transform:uppercase;color:var(--faint,var(--muted))}
.osApp.osMap .osMapLegend .osMapLgs{gap:3px}
.osApp.osMap .osMapLegend .osMapLg{font-size:11.5px;color:var(--ink)}
.osApp.osMap .osMapWhy summary{
  margin-top:8px;font:600 11px/1.4 var(--body);color:var(--muted);cursor:pointer}
.osApp.osMap .osMapWhy summary:hover{color:var(--ink)}
.osApp.osMap .osMapWhy p{margin:6px 0 0;font-size:11px}
.osApp.osMap .osMapBubbles i{border:1px solid currentColor}
/* ── the world's ground IS the stage, and ONLY the stage ────────────────────
   ⛔ The picture must sit on the WORLD, not on cream. `.osMapPic` carried its
   own `--cream2` background and its own `--bc-map-ground`, so a night scene
   drew amber bubbles on a pale rectangle — measured in a browser 2026-09-09,
   and it is the whole reason a world exists. The stage is the map: the canvas
   when it has painted, the still picture when it has not. Nothing outside the
   stage reads `--w-ground`.
   ⛔ Ink too: the SVG draws its outlines in `currentColor`. */
.osApp.osMap .osMapWorld .osMapStage{background:var(--w-ground)}
.osApp.osMap .osMapWorld .osMapPic{
  background:transparent;box-shadow:none;border-radius:0;
  --bc-map-ground:var(--w-ground);color:var(--w-ink)}
.osApp.osMap .osMapWorld .osMapPic .bc-map{max-width:none;width:100%}

/* ⛔ The search's explanation is available, not displayed: it is the field's
   aria-description, shown when the field has focus. "User don't read" — but a
   screen reader does, and a person who pauses on the field deserves it. */
.osApp.osMap .osMapOver .osMapSearchWhy{
  max-height:0;overflow:hidden;margin:0;opacity:0;transition:max-height .18s ease,opacity .18s ease}
.osApp.osMap .osMapOver .osMapTopL:focus-within .osMapSearchWhy{max-height:7em;opacity:1;margin:6px 0 0}
@media (prefers-reduced-motion:reduce){
  .osApp.osMap .osMapOver .osMapSearchWhy{transition:none}
}

/* ── the sample / busy / drawing card: a cream plate, same as the caption ── */
.osApp.osMap .osMapSample{
  /* ⛔ Centred in the room BELOW the caption, not in the whole stage — measured
     2026-09-10: centred in the stage, the card's stamp slid under the caption
     plate. The top chrome is ~210 px tall; the card centres in what is left. */
  position:absolute;inset:0;display:grid;place-items:center;padding:210px 24px 70px;z-index:2}
.osApp.osMap .osMapSampleIn{
  max-width:30em;display:grid;gap:8px;justify-items:start;padding:18px 20px;
  background:color-mix(in srgb, var(--panel) 96%, transparent);
  border:1px solid var(--line);color:var(--ink);
  border-radius:var(--r,22px);box-shadow:var(--lift-2,var(--lift,none));
  backdrop-filter:blur(10px)}
.osApp.osMap .osMapSampleIn b{font:800 19px/1.2 var(--disp,var(--body));color:var(--ink)}
.osApp.osMap .osMapSampleIn p{margin:0;font:500 13.5px/1.55 var(--body);color:var(--ink)}
.osApp.osMap .osMapSampleIn p.why,
.osApp.osMap .osMapSampleIn p.task{font-size:12px;color:var(--muted)}
.osApp.osMap .osMapSampleIn code{font:600 11px var(--mono,var(--osMono,ui-monospace,monospace));color:var(--ink)}
.osApp.osMap .osMapSampleIn .go{display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin-top:4px}
.osApp.osMap .osMapSampleIn .go>span{
  font:600 9.5px/1 var(--mono,var(--osMono,ui-monospace,monospace));letter-spacing:.12em;text-transform:uppercase;
  color:var(--faint,var(--muted))}

/* ── the loop's own control ─────────────────────────────────────────────── */
.osApp.osMap .osMapPlay{min-width:34px;padding:6px 9px;font-size:11px;line-height:1}
.osApp.osMap .osMapPlay[aria-pressed="true"]{background:var(--fill);color:var(--onfill);border-color:transparent}
/* the loading card reads as work in progress, not as a result */
.osApp.osMap .osMapSampleIn.loading{opacity:.9}
.osApp.osMap .osMapSampleIn.loading p.why{
  display:inline-flex;align-items:center;gap:8px}
.osApp.osMap .osMapSampleIn.loading p.why::before{
  content:"";width:10px;height:10px;border-radius:50%;
  border:2px solid currentColor;border-top-color:transparent;
  animation:osMapSpin .8s linear infinite}
@keyframes osMapSpin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){
  .osApp.osMap .osMapSampleIn.loading p.why::before{animation:none;border-top-color:currentColor;opacity:.5}
}
/* ⚡ the stage cross-fades when a scene changes — the one motion that makes
   twenty-four scenes read as one app rather than twenty-four page loads */
.osApp.osMap .osMapStage{transition:opacity .18s ease,background .35s ease}
.osApp.osMap .osMapStage[aria-busy="true"]{opacity:.72}
@media (prefers-reduced-motion:reduce){ .osApp.osMap .osMapStage{transition:none} }

/* ── the time control floats with the chrome, bottom-centre — a cream pill ── */
.osApp.osMap .osMapTimeSlot{display:flex;justify-content:center}
.osApp.osMap .osMapTimeSlot .osMapTime{
  pointer-events:auto;margin:0;max-width:min(46em,100%);
  background:color-mix(in srgb, var(--panel) 96%, transparent);
  border:1px solid var(--line);border-radius:var(--r-pill,999px);color:var(--ink);
  box-shadow:var(--lift,none);
  backdrop-filter:blur(10px) saturate(1.05);padding:7px 12px}

/* ⛔ The transport controls never wrap away from the year. Measured 2026-09-10:
   squeezed between the legend and the source line, the "next year" button
   dropped to a second row under the pause — two halves of one control in two
   places. The sentence under it may wrap; the buttons may not. */
.osApp.osMap .osMapTimeSlot .osMapTime{
  display:grid;grid-template-columns:auto auto auto minmax(7em,1fr) auto;
  align-items:center;gap:8px;row-gap:2px;min-width:min(26em,100%)}
.osApp.osMap .osMapTimeSlot .osMapTicks{display:none}
/* ⛔ The two summaries share ONE row. Stacked, each on its own full-width row,
   the pill grew to 137 px — a floating control taller than it is useful. */
.osApp.osMap .osMapTimeSlot .osMapFrameState,
.osApp.osMap .osMapTimeSlot .osMapHint{
  font-size:11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
.osApp.osMap .osMapTimeSlot .osMapFrameState{grid-column:1/4;justify-self:start}
.osApp.osMap .osMapTimeSlot .osMapHint{grid-column:4/-1;justify-self:end}
@media (max-width:900px){
  .osApp.osMap .osMapTimeSlot .osMapTime{grid-template-columns:auto auto auto minmax(4em,1fr) auto}
  .osApp.osMap .osMapTimeSlot .osMapTicks{display:none}
}
