/* Al Rasd — stylesheet.
   Tokens, type scale and components follow "Al Rasd - Design.html": a paper-light
   public site with a greyscale map, and a control panel with a dark sidebar
   against the same light work area. Colour is reserved for the accent, the live
   indicator, and the protection warning.

   Two families of token, and the difference matters. The chrome tokens —
   --paper, --sheet, --ink and the rest — describe the page. The --map-* tokens
   describe things drawn ON the map: markers, their rings, their labels, the
   cluster discs, Leaflet's own controls. Those must stay dark on light whatever
   the chrome does, so they never reference --ink or --sheet. */

:root {
  --paper:       oklch(0.968 0.002 260);   /* the ground everything sits on */
  --sheet:       oklch(0.995 0.001 260);   /* a raised surface: card, table, bar */
  --sheet-2:     oklch(0.955 0.002 260);   /* a recessed one: hover, track */
  --ink:         oklch(0.17 0.006 260);
  --ink-2:       oklch(0.42 0.006 260);
  --ink-3:       oklch(0.60 0.005 260);
  --line:        oklch(0.905 0.003 260);
  --line-2:      oklch(0.945 0.002 260);
  --accent:      oklch(0.55 0.19 26);
  --accent-2:    oklch(0.55 0.19 26);
  --accent-deep: oklch(0.38 0.12 26);
  --accent-soft: oklch(0.955 0.02 26);
  --ok:          oklch(0.55 0.09 160);
  --warn-line:   oklch(0.80 0.02 60);
  --warn-ink:    oklch(0.50 0.06 60);
  --shadow:      oklch(0.17 0.006 260 / .18);
  --shadow-soft: oklch(0.17 0.006 260 / .07);

  /* Drawn on the map, which is light. Never derived from the chrome. */
  --map-ring:    oklch(0.995 0.001 260);
  --map-ink:     oklch(0.19 0.006 260);
  --map-ink-2:   oklch(0.44 0.006 260);
  --map-ink-3:   oklch(0.62 0.005 260);
  --map-line:    oklch(0.885 0.003 260);

  /* Neither Instrument Sans nor IBM Plex Mono draws Arabic, so Arabic text was
     falling through to whatever the operating system happened to supply and
     looked different on every machine. IBM Plex Sans Arabic is the companion
     face to Plex Mono and catches those glyphs by unicode-range, so Latin
     still renders in the design's own type and only Arabic changes hands. */
  --mono: 'IBM Plex Mono', 'IBM Plex Sans Arabic', ui-monospace, monospace;
  --sans: 'Instrument Sans', 'IBM Plex Sans Arabic', system-ui, sans-serif;
}

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body {
  font-family: var(--sans); background: var(--paper); color: var(--ink);
  font-size: 14px; -webkit-font-smoothing: antialiased; overflow: hidden;
}
a { color: var(--accent); text-decoration: none; }
a:hover { color: oklch(0.42 0.19 26); }
button { font: inherit; color: inherit; border: none; background: none; cursor: pointer; }
h1, h2, h3, h4, h5, h6 { margin: 0; font-weight: 600; }
p { margin: 0 0 .85em; }
::selection { background: var(--ink); color: var(--sheet); }

.mono { font-family: var(--mono); }
.lbl {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .11em;
  text-transform: uppercase; color: var(--ink-3);
}
.muted { color: var(--ink-3); }
.small { font-size: 12px; }
.spacer { flex: 1; }
.empty { text-align: center; color: var(--ink-3); padding: 44px 20px; font-size: 13px; }
.divider { width: 1px; height: 22px; background: var(--line); flex: none; }
.hr { height: 1px; background: var(--line); margin: 18px 0; }

/* --- RTL ------------------------------------------------------------------ */
/* Arabic is a joined script. The tracking that gives the design its small-caps
   mono labels their look pulls the joins apart, so الأحداث renders as a row of
   disconnected shapes — the single most visible thing wrong with the Arabic
   side. Tracking is a Latin typographic device; it is dropped wholesale while
   the page is Arabic and left untouched in English. The !important is load
   bearing: it has to beat 35 individual letter-spacing declarations. */
[dir="rtl"] * { letter-spacing: normal !important; }

[dir="rtl"] .feed { border-left: 0; border-right: 1px solid var(--line); }
[dir="rtl"] .layers { right: auto; left: 14px; }
[dir="rtl"] .legend { left: auto; right: 14px; }
[dir="rtl"] .side a.on { box-shadow: inset -2px 0 0 var(--accent); }
[dir="rtl"] .quote { border-left: 0; border-right: 2px solid var(--ink); padding: 2px 12px 2px 0; }

/* --- Buttons and controls ------------------------------------------------- */

.btn {
  font-size: 12.5px; padding: 7px 13px; border: 1px solid var(--line);
  border-radius: 5px; background: var(--sheet); color: var(--ink);
  display: inline-flex; align-items: center; gap: 6px; justify-content: center;
  white-space: nowrap; transition: border-color .12s, background .12s;
}
.btn:hover:not(:disabled) { border-color: var(--ink-3); }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn-dark { background: var(--ink); color: var(--sheet); border-color: var(--ink); }
.btn-dark:hover:not(:disabled) { background: oklch(0.28 0.006 260); border-color: oklch(0.28 0.006 260); }
.btn-danger { border-color: var(--accent); color: var(--accent); }
.btn-danger:hover:not(:disabled) { background: var(--accent-soft); }
.btn-ghost { border-color: transparent; background: transparent; color: var(--ink-2); }
.btn-ghost:hover:not(:disabled) { background: var(--paper); color: var(--ink); border-color: transparent; }
.btn-sm { padding: 4px 9px; font-size: 11.5px; }
.btn-block { display: flex; width: 100%; }
.wbtn { display: block; width: 100%; text-align: center; margin-top: 4px; padding: 10px; border-radius: 6px; font-size: 13px; }

.seg { display: flex; border: 1px solid var(--line); border-radius: 5px; overflow: hidden; flex: none; }
.seg button {
  font-family: var(--mono); font-size: 10px; letter-spacing: .06em; text-transform: uppercase;
  padding: 6px 11px; color: var(--ink-2); border-right: 1px solid var(--line); background: var(--sheet);
}
.seg button:last-child { border-right: none; }
.seg button:hover { background: var(--paper); }
.seg button.on { background: var(--ink); color: var(--sheet); }
/* A segmented control on its own line rather than in a toolbar: the choices
   share the width instead of hugging their labels. */
.seg-block { display: flex; width: 100%; margin-top: 8px; }
.seg-block button { flex: 1; min-width: 0; text-align: center; }

input, select, textarea {
  width: 100%; padding: 8px 10px; border: 1px solid var(--line); border-radius: 5px;
  background: var(--sheet); color: var(--ink); font: 400 12.5px var(--sans); outline: none;
}
input:focus, select:focus, textarea:focus { border-color: var(--ink-3); }
textarea { resize: vertical; min-height: 78px; line-height: 1.55; font-size: 13px; }
label {
  display: block; font-family: var(--mono); font-size: 9px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-3); margin-bottom: 4px;
}
.field { margin-bottom: 13px; }
.field .help { font-size: 11.5px; color: var(--ink-3); margin-top: 5px; line-height: 1.45; text-transform: none; letter-spacing: 0; font-family: var(--sans); }
.row { display: flex; gap: 10px; }
.row > * { flex: 1; min-width: 0; }
.check { display: flex; align-items: center; gap: 8px; cursor: pointer; margin-bottom: 0; text-transform: none; letter-spacing: 0; font-family: var(--sans); font-size: 12.5px; color: var(--ink); }
.check input { width: auto; margin: 0; accent-color: var(--ink); }

.chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--mono); font-size: 8.5px; letter-spacing: .08em; text-transform: uppercase;
  padding: 2px 6px; border: 1px solid var(--line); border-radius: 3px; color: var(--ink-2);
  white-space: nowrap;
}
.chip.c, .chip.confirmed { border-color: var(--ink); color: var(--ink); }
.chip.r, .chip.reported  { border-color: var(--warn-line); color: var(--warn-ink); }
.chip.a, .chip.accent    { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.chip.probable   { border-color: var(--ink-3); color: var(--ink-2); }
.chip.unverified { border-color: var(--line); color: var(--ink-3); }
.chip.restricted { border-color: var(--warn-line); color: var(--warn-ink); background: oklch(0.97 0.02 60); }
.chip.vault      { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.chip.draft      { border-style: dashed; color: var(--ink-3); }
.chip.published  { border-color: var(--ok); color: var(--ok); }

.card { background: var(--sheet); border: 1px solid var(--line); border-radius: 7px; box-shadow: 0 2px 14px var(--shadow-soft); }
.box { background: var(--sheet); border: 1px solid var(--line); border-radius: 7px; padding: 16px; }

.spinner {
  width: 14px; height: 14px; border: 2px solid var(--line);
  border-top-color: var(--ink); border-radius: 50%;
  animation: spin .7s linear infinite; display: inline-block;
}
@keyframes spin { to { transform: rotate(360deg); } }

.dot { width: 6px; height: 6px; border-radius: 999px; background: var(--accent); animation: pulse 2s infinite; flex: none; }
@keyframes pulse { 0%, 100% { opacity: 1 } 50% { opacity: .25 } }
.live { display: flex; align-items: center; gap: 6px; font-family: var(--mono); font-size: 9.5px; letter-spacing: .11em; text-transform: uppercase; color: var(--accent); }

/* --- Toasts --------------------------------------------------------------- */
#toasts { position: fixed; bottom: 16px; right: 16px; z-index: 9999; display: flex; flex-direction: column; gap: 8px; }
.toast {
  background: var(--ink); color: var(--sheet); border-radius: 6px; padding: 10px 14px;
  box-shadow: 0 4px 18px oklch(0.17 0.006 260 / .3); max-width: 380px; font-size: 12.5px;
  animation: slidein .18s ease-out; border-left: 3px solid var(--ink-3);
}
.toast.ok { border-left-color: var(--ok); }
.toast.warn { border-left-color: var(--accent); }
@keyframes slidein { from { transform: translateY(8px); opacity: 0 } }

/* --- Public shell --------------------------------------------------------- */

.app { display: flex; flex-direction: column; height: 100vh; }

.topbar {
  height: 54px; flex: none; display: flex; align-items: center; gap: 18px; padding: 0 18px;
  background: var(--sheet); border-bottom: 1px solid var(--line); position: relative; z-index: 1000;
}
.wordmark { display: flex; align-items: baseline; gap: 9px; color: var(--ink); }
.wordmark b { font-size: 16px; font-weight: 600; letter-spacing: -.02em; }
.wordmark span { font-family: var(--mono); font-size: 9px; letter-spacing: .15em; text-transform: uppercase; color: var(--ink-3); }
.navlink { font-size: 13px; color: var(--ink-2); }
.navlink:hover { color: var(--ink); }
.navlink.on { color: var(--ink); font-weight: 500; }
.search {
  flex: 1; max-width: 300px; display: flex; align-items: center; gap: 8px; height: 32px;
  padding: 0 11px; border: 1px solid var(--line); border-radius: 5px; background: var(--paper);
}
.search input { border: none; background: none; padding: 0; height: 30px; font-size: 12.5px; }
.search input::placeholder { color: var(--ink-3); }
.search .k { font-family: var(--mono); font-size: 10px; color: var(--ink-3); flex: none; }

.main { flex: 1; display: flex; min-height: 0; }

/* --- Map ------------------------------------------------------------------ */

.maparea { position: relative; flex: 1; display: flex; min-width: 0; }
.mapwrap { position: relative; flex: 1; min-width: 0; }
/* The map keeps its own light ground whatever the chrome does — a reader is
   looking at land, and land reads on paper. Set explicitly rather than
   inherited, so the moment before tiles arrive is a blank map rather than a
   hole in the page. */
#map { position: absolute; inset: 0; background: oklch(0.945 0.004 250); }
.leaflet-container { background: oklch(0.945 0.004 250); font-family: var(--sans); }
/* The cartography is muted so icons and control fills carry the colour. */
/* Clicking a territory focuses its SVG path, and browsers draw that focus ring
   around the element's bounding box — a black rectangle across the map that
   has nothing to do with the shape underneath. Keyboard focus keeps a ring, so
   the map stays navigable without a mouse. */
.leaflet-interactive:focus { outline: none; }
.leaflet-interactive:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Shift-drag on the territory map draws this instead of Leaflet's box-zoom:
   lassoing a front is worth more here than zooming to a rectangle. */
.map-select-box {
  position: absolute; z-index: 800; pointer-events: none;
  border: 1.5px dashed var(--accent);
  background: oklch(0.62 0.16 250 / .12);
  border-radius: 2px;
}

/* The raster basemap is a full-colour street map, muted here so the category
   pills and territory fills carry the only colour on the page. */
.leaflet-tile-pane { filter: grayscale(1) contrast(.72) brightness(1.13); }
/* MapTiler's dataviz-light is already a muted grey basemap built for data
   overlay, so it is left alone — filtering it again washes the labels out
   until Arabic place names are unreadable. */
.has-vector-basemap .leaflet-tile-pane,
.has-vector-basemap .maplibregl-canvas-container,
.has-vector-basemap .maptiler-sdk-canvas-container { filter: none; }
.leaflet-control-zoom { border: 1px solid var(--line) !important; border-radius: 5px !important; overflow: hidden; box-shadow: none !important; }
.leaflet-control-zoom a { background: var(--map-ring) !important; color: var(--map-ink) !important; border-bottom-color: var(--map-line) !important; width: 30px !important; height: 30px !important; line-height: 29px !important; }
.leaflet-control-attribution { background: oklch(0.995 0.001 260 / .82) !important; font-size: 9px !important; font-family: var(--mono); color: var(--ink-3) !important; }
.leaflet-control-attribution a { color: var(--ink-2) !important; }
.leaflet-marker-icon { background: none; border: none; }

/* --- Map markers ---------------------------------------------------------
   Two shapes, and the difference between them is the whole point. A round disc
   is a report: something that happened, filled with its family's colour so a
   theatre reads as red or blue from across the room. A square tile is a site:
   something that stands, drawn in the page colour and outlined in the colour of
   whoever holds it, so the furniture of the map never shouts over the news.

   Both ride on --c, set inline from the row's colour, so a hover or a selection
   changes one custom property rather than rebuilding the marker. */

.pin-icon { background: none; border: 0; }
.pin-wrap { display: flex; flex-direction: column; align-items: center; gap: 3px; }

.pin {
  display: grid; place-items: center; flex: none; cursor: pointer;
  color: #fff; background: var(--c); border-radius: 999px;
  box-shadow: 0 0 0 2px var(--map-ring), 0 1px 5px oklch(0.17 0.006 260 / .3);
  transition: transform .12s ease, box-shadow .12s ease;
}
.pin svg { display: block; }
.pin:hover { transform: scale(1.14); z-index: 2; }

/* A site is the inversion: page-coloured tile, holder-coloured edge and glyph. */
.pin-site {
  border-radius: 6px; color: var(--c); background: var(--map-ring);
  box-shadow: inset 0 0 0 2px var(--c), 0 1px 4px oklch(0.17 0.006 260 / .22);
}

/* The last six hours. A ring rather than a different fill, so "new" and "what
   kind" are two separate readings of the same marker. */
.pin.is-recent { box-shadow: 0 0 0 2px var(--map-ring), 0 0 0 4.5px var(--c), 0 1px 6px oklch(0.17 0.006 260 / .3); }

/* States of the record, not of the world — panel-only, and muted on purpose. */
.pin.is-draft     { opacity: .78; box-shadow: 0 0 0 2px var(--map-ring), 0 0 0 3px oklch(0.60 0.005 260 / .85); }
.pin.is-suggestion{ background: var(--map-ring); color: var(--map-ink-3); box-shadow: 0 0 0 2px var(--map-ring), 0 0 0 2px var(--map-ink-3); }
.pin.is-locked    { background: var(--map-ring); color: var(--map-ink); box-shadow: 0 0 0 2px var(--map-ring), 0 0 0 1.5px var(--map-ink); }
.pin.is-hi, .pin.is-selected { transform: scale(1.2); box-shadow: 0 0 0 2px var(--map-ring), 0 0 0 6px oklch(0.17 0.006 260 / .16); }

/* A site only reported is drawn as a guess; one that has stopped being a place
   fades rather than vanishing, because it was there. */
.pin-site.s-suspected { box-shadow: inset 0 0 0 2px var(--c); opacity: .82; border-style: dashed; }
.pin-site.s-contested { box-shadow: inset 0 0 0 2px var(--c), 0 0 0 2px oklch(0.55 0.19 26 / .45); }
.pin-site.s-abandoned,
.pin-site.s-destroyed { opacity: .5; }

.pin-label {
  max-width: 128px; padding: 1px 5px; border-radius: 3px;
  background: oklch(0.995 0.001 260 / .88); border: 1px solid var(--map-line);
  font-family: var(--mono); font-size: 9px; letter-spacing: .03em;
  color: var(--map-ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  pointer-events: none;
}

.cluster {
  display: grid; place-items: center; border-radius: 999px; background: var(--map-ink); color: var(--map-ring);
  font-family: var(--mono); font-size: 10.5px; border: 2px solid var(--map-ring);
  box-shadow: 0 2px 8px oklch(0.17 0.006 260 / .25); cursor: pointer;
}

/* Glass over the map. The blur is what keeps a panel legible when a city sits
   under it, and the border is what stops it dissolving into one. */
.overlay {
  position: absolute; z-index: 800;
  background: oklch(0.995 0.001 260 / .92);
  border: 1px solid var(--line);
  box-shadow: 0 6px 26px oklch(0.17 0.006 260 / .16);
  backdrop-filter: blur(9px) saturate(120%);
  -webkit-backdrop-filter: blur(9px) saturate(120%);
  color: var(--ink);
}

/* Both map panels collapse to their header. A legend of fifty actors and a
   layer list are useful twice a session and in the way for the rest of it, and
   neither used to be dismissible at all — the single loudest complaint about
   this screen. The choice is remembered per browser. */
.panelhead {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 9px 12px; cursor: pointer; background: none; border: 0;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .11em;
  text-transform: uppercase; color: var(--ink-3); text-align: start;
}
.panelhead:hover { color: var(--ink-2); }
.panelhead .caret { margin-inline-start: auto; font-size: 10px; transition: transform .16s; }
.overlay.collapsed .panelhead .caret { transform: rotate(-90deg); }
[dir="rtl"] .overlay.collapsed .panelhead .caret { transform: rotate(90deg); }
.panelbody { padding: 0 12px 11px; }
.overlay.collapsed { max-height: none; }
.overlay.collapsed .panelbody { display: none; }

.legend { left: 14px; bottom: 108px; width: 216px; border-radius: 8px; max-height: calc(100vh - 220px); display: flex; flex-direction: column; }
.legend .panelbody { display: flex; flex-direction: column; min-height: 0; }
.legend-actors { overflow-y: auto; min-height: 0; }
.legend .row { display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: var(--ink-2); padding: 3px 0; }
.sw { width: 15px; height: 11px; border-radius: 2px; flex: none; border: 1px solid oklch(0.17 0.006 260 / .3); }
.sw.hatch { background: repeating-linear-gradient(135deg, transparent 0 3px, oklch(0.17 0.006 260 / .35) 3px 4px); }

.layers { right: 14px; top: 14px; width: 250px; border-radius: 8px; max-height: calc(100% - 150px); overflow-y: auto; }
.layers .panelbody { padding: 0 0 6px; }
.layers h4 { margin: 0; padding: 9px 13px 5px; font-family: var(--mono); font-size: 9px; letter-spacing: .11em; text-transform: uppercase; color: var(--ink-3); }
.lrow { display: flex; align-items: center; gap: 9px; padding: 6px 13px; font-size: 12.5px; cursor: pointer; }
.lrow:hover { background: var(--paper); }
.lrow .meta { margin-left: auto; font-family: var(--mono); font-size: 9px; color: var(--ink-3); }
.tg { width: 26px; height: 15px; border-radius: 999px; background: var(--line); flex: none; position: relative; transition: .15s; }
.tg::after { content: ""; position: absolute; top: 2px; left: 2px; width: 11px; height: 11px; border-radius: 999px; background: var(--sheet); transition: .15s; box-shadow: 0 1px 2px oklch(0.17 0.006 260 / .3); }
.tg.on { background: var(--ink); }
.tg.on::after { left: 13px; }
.lrow.locked { color: var(--ink-3); }
.lrow.locked .tg { opacity: .45; }

/* --- Feed ----------------------------------------------------------------- */

.feed { width: 396px; flex: none; background: var(--sheet); border-left: 1px solid var(--line); display: flex; flex-direction: column; min-height: 0; }
.feedhead { padding: 13px 16px 11px; border-bottom: 1px solid var(--line); display: flex; align-items: center; gap: 9px; flex: none; }
.feedlist { flex: 1; overflow-y: auto; overscroll-behavior: contain; }

.ev { padding: 14px 16px; border-bottom: 1px solid var(--line-2); cursor: pointer; }
.ev:hover { background: var(--paper); }
.ev.sel, .ev.hi { background: var(--paper); box-shadow: inset 2px 0 0 var(--ink); }
.evtop { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; flex-wrap: wrap; }
.time { font-family: var(--mono); font-size: 10px; color: var(--ink-3); letter-spacing: .03em; }
.ev h5 { margin: 0 0 5px; font-size: 14px; font-weight: 600; line-height: 1.35; letter-spacing: -.008em; }
.ev p { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--ink-2); }
.evfoot { display: flex; align-items: center; gap: 12px; margin-top: 8px; font-family: var(--mono); font-size: 9.5px; color: var(--ink-3); flex-wrap: wrap; }
.ev .body { display: none; margin-top: 10px; padding-top: 11px; border-top: 1px solid var(--line-2); }
.ev.sel .body { display: block; }
.ev .body p { margin: 0 0 9px; font-size: 12.5px; line-height: 1.62; color: var(--ink-2); }
.srcs { display: flex; flex-direction: column; gap: 5px; margin-top: 4px; }
.src { display: flex; align-items: center; gap: 8px; font-family: var(--mono); font-size: 10px; color: var(--ink-2); }
.src b { font-weight: 500; color: var(--ink); }

.ev.locked, .lockedcard {
  padding: 14px 16px; border-bottom: 1px solid var(--line-2); cursor: pointer;
  background: repeating-linear-gradient(135deg, transparent 0 7px, oklch(0.17 0.006 260 / .022) 7px 8px);
}
.lockedcard .t { font-size: 12.5px; color: var(--ink-2); margin-bottom: 7px; }
.blur { height: 10px; border-radius: 3px; background: oklch(0.17 0.006 260 / .07); margin-bottom: 6px; }
.blur.w2 { width: 74%; } .blur.w3 { width: 48%; }

.adslot {
  padding: 16px; border-bottom: 1px solid var(--line-2); text-align: center;
  background: repeating-linear-gradient(90deg, var(--paper) 0 6px, var(--sheet) 6px 12px);
}
.adslot .lbl { margin-bottom: 4px; display: block; }
.adslot .adbox { border: 1px dashed var(--line); border-radius: 5px; padding: 22px; background: var(--sheet); font-family: var(--mono); font-size: 10px; color: var(--ink-3); }

.upsell { padding: 16px; border-bottom: 1px solid var(--line-2); background: var(--accent-soft); }
.upsell h5 { font-size: 13px; margin-bottom: 5px; }
.upsell p { font-size: 12px; color: var(--ink-2); line-height: 1.5; margin-bottom: 10px; }

.newpill {
  position: absolute; top: 14px; left: 50%; transform: translateX(-50%); z-index: 830;
  background: var(--ink); color: var(--sheet); border-radius: 999px; padding: 7px 15px;
  font-family: var(--mono); font-size: 10px; letter-spacing: .06em; text-transform: uppercase;
  box-shadow: 0 3px 14px oklch(0.17 0.006 260 / .28);
}

/* --- Timeline ------------------------------------------------------------- */

.timeline { left: 14px; right: 14px; bottom: 14px; padding: 10px 14px 11px; z-index: 810; }
.tlhead { display: flex; align-items: center; flex-wrap: wrap; gap: 7px 10px; margin-bottom: 9px; }
.track { height: 26px; position: relative; border-radius: 4px; overflow: hidden; background: var(--paper); border: 1px solid var(--line-2); cursor: pointer; }
.track .bars { position: absolute; inset: 0; display: flex; align-items: flex-end; gap: 1px; padding: 0 1px; }
.track .bars div { flex: 1; background: oklch(0.17 0.006 260 / .18); }
.lockzone {
  position: absolute; top: 0; bottom: 0; left: 0;
  background: repeating-linear-gradient(135deg, oklch(0.995 0.001 260 / .82) 0 5px, oklch(0.90 0.003 260 / .8) 5px 6px);
  display: flex; align-items: center; justify-content: center;
}
.lockzone span { font-family: var(--mono); font-size: 9px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-2); background: var(--sheet); padding: 2px 8px; border-radius: 3px; border: 1px solid var(--line); }
.head-now { position: absolute; top: -4px; bottom: -4px; width: 2px; background: var(--accent); }
.track input[type=range] { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; margin: 0; }

/* --- Long-form pages ------------------------------------------------------ */

.page { flex: 1; overflow-y: auto; background: var(--paper); }
.wrap { max-width: 1180px; margin: 0 auto; padding: 56px 32px 80px; }
.wrap.narrow { max-width: 760px; }
.h1 { font-size: 44px; font-weight: 600; letter-spacing: -.03em; line-height: 1.05; margin: 0 0 12px; text-wrap: balance; }
.h2 { font-size: 22px; font-weight: 600; letter-spacing: -.02em; margin: 0 0 10px; }
.lede { font-size: 16.5px; line-height: 1.5; color: var(--ink-2); margin: 0 0 40px; max-width: 36em; }

.prose { font-size: 14.5px; line-height: 1.7; color: var(--ink-2); max-width: 40em; }
.prose p { margin: 0 0 1.1em; }
.prose h2 { font-size: 19px; color: var(--ink); margin: 1.9em 0 .6em; }
.prose h3 { font-size: 16px; color: var(--ink); margin: 1.6em 0 .5em; }
.prose ul, .prose ol { padding-left: 1.3em; margin: 0 0 1.1em; }
.prose li { margin-bottom: .4em; }
.prose blockquote { border-left: 2px solid var(--ink); padding-left: 13px; margin: 1.2em 0; color: var(--ink-2); }
.prose strong { color: var(--ink); font-weight: 600; }
.prose code { font-family: var(--mono); font-size: 12.5px; background: var(--paper); padding: 1px 5px; border-radius: 3px; }

.plans { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; border: 1px solid var(--line); border-radius: 9px; overflow: hidden; background: var(--sheet); }
.plan { padding: 24px 22px 26px; border-right: 1px solid var(--line); display: flex; flex-direction: column; }
.plan:last-child { border-right: none; }
.plan.feat { background: var(--paper); box-shadow: inset 0 2px 0 var(--accent); }
.plan.feat .lbl { color: var(--accent); }
.plan.feat .price small, .plan.feat li { color: var(--ink-2); }
.plan h3 { margin: 8px 0 3px; font-size: 17px; font-weight: 600; letter-spacing: -.01em; }
.price { font-size: 34px; font-weight: 600; letter-spacing: -.035em; margin: 10px 0 4px; }
.price small { font-size: 12.5px; font-weight: 400; letter-spacing: 0; color: var(--ink-3); }
.plan .sub { font-size: 12.5px; color: var(--ink-2); min-height: 34px; margin: 0 0 16px; }
.plan.feat .sub { color: var(--ink-2); }
.plan ul { list-style: none; margin: 16px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.plan li { font-size: 12.5px; line-height: 1.4; color: var(--ink-2); display: flex; gap: 8px; }
.plan li i { font-style: normal; font-family: var(--mono); font-size: 10px; color: var(--ink); flex: none; margin-top: 1px; }
.plan.feat li i { color: var(--accent); }
.plan li.no { color: var(--ink-3); }
.plan.feat .btn { background: var(--ink); color: var(--paper); border-color: var(--ink); }

.rule { display: flex; gap: 14px; align-items: flex-start; margin-top: 22px; padding: 18px 20px; }
.rule .tag { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--accent); border: 1px solid var(--accent); border-radius: 3px; padding: 3px 7px; flex: none; }
.rule p { margin: 0; font-size: 13px; line-height: 1.6; color: var(--ink-2); }

.paywall { margin-top: 26px; padding: 26px; text-align: center; border: 1px solid var(--line); border-radius: 8px; background: var(--sheet); }

.grid { display: grid; gap: 14px; }
.grid.c2 { grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }
.grid.c3 { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
.grid.c4 { grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); }

/* --- Dialogs -------------------------------------------------------------- */

.sheet-backdrop, .modal-backdrop { position: fixed; inset: 0; background: oklch(0.17 0.006 260 / .32); z-index: 2000; animation: fade .15s; }
@keyframes fade { from { opacity: 0 } }
.modal-backdrop { display: grid; place-items: center; padding: 20px; }
.modal { background: var(--sheet); border: 1px solid var(--line); border-radius: 9px; width: min(520px, 100%); max-height: 88vh; display: flex; flex-direction: column; box-shadow: 0 20px 60px var(--shadow); }
.modal-head { padding: 15px 18px; border-bottom: 1px solid var(--line); display: flex; align-items: center; gap: 10px; }
.modal-head h2 { font-size: 15px; flex: 1; letter-spacing: -.01em; }
.modal-body { padding: 18px; overflow-y: auto; }
.modal-foot { padding: 13px 18px; border-top: 1px solid var(--line); display: flex; gap: 8px; justify-content: flex-end; }

.sheet { position: fixed; top: 0; right: 0; bottom: 0; width: min(640px, 100vw); background: var(--sheet); border-left: 1px solid var(--line); z-index: 2001; display: flex; flex-direction: column; box-shadow: -12px 0 40px var(--shadow); animation: slidex .2s cubic-bezier(.2,.8,.3,1); }
[dir="rtl"] .sheet { right: auto; left: 0; border-left: 0; border-right: 1px solid var(--line); }
@keyframes slidex { from { transform: translateX(24px); opacity: .6 } }
.sheet-head { padding: 14px 18px; border-bottom: 1px solid var(--line); display: flex; align-items: center; gap: 10px; flex: none; }
.sheet-head h2 { font-size: 15px; flex: 1; letter-spacing: -.015em; }
.sheet-body { flex: 1; overflow-y: auto; padding: 18px; }

/* --- Panel ---------------------------------------------------------------- */

.panel { display: flex; height: 100vh; }
/* The one dark surface in the panel, and it was dark in the original design:
   a navigation rail beside a light work area. Its colours are written out
   rather than taken from --ink, which is the page's dark text, not this. */
.side { width: 216px; flex: none; background: var(--ink); color: oklch(0.80 0.004 260); display: flex; flex-direction: column; padding: 16px 0; overflow-y: auto; }
.side .brand { padding: 0 18px 18px; display: flex; align-items: baseline; gap: 8px; color: var(--sheet); }
.side .brand b { font-size: 14.5px; font-weight: 600; letter-spacing: -.01em; }
.side .brand span { font-family: var(--mono); font-size: 8.5px; letter-spacing: .15em; text-transform: uppercase; color: oklch(0.62 0.004 260); }
.side h6 { margin: 16px 0 4px; padding: 0 18px; font-family: var(--mono); font-size: 8.5px; letter-spacing: .13em; text-transform: uppercase; color: oklch(0.55 0.004 260); }
.side a { display: flex; align-items: center; gap: 9px; padding: 6px 18px; font-size: 12.5px; color: oklch(0.80 0.004 260); cursor: pointer; }
.side a:hover { color: var(--sheet); background: oklch(0.24 0.006 260); text-decoration: none; }
.side a.on { color: var(--sheet); background: oklch(0.27 0.006 260); box-shadow: inset 2px 0 0 var(--accent); }
.side a .n { margin-left: auto; font-family: var(--mono); font-size: 9.5px; background: var(--accent); color: #fff; padding: 1px 5px; border-radius: 3px; }
.side .user { margin-top: auto; padding: 14px 18px 0; border-top: 1px solid oklch(0.28 0.006 260); font-size: 12px; color: var(--sheet); }
.side .user span { display: block; font-family: var(--mono); font-size: 9px; letter-spacing: .08em; text-transform: uppercase; color: oklch(0.58 0.004 260); margin-top: 2px; }

.work { flex: 1; display: flex; flex-direction: column; min-width: 0; background: var(--paper); }
.wbar { height: 52px; flex: none; display: flex; align-items: center; gap: 14px; padding: 0 20px; background: var(--sheet); border-bottom: 1px solid var(--line); }
.wbar h2 { margin: 0; font-size: 15px; font-weight: 600; letter-spacing: -.012em; }
.wbody { flex: 1; overflow-y: auto; padding: 22px 26px 40px; }
.wbody.flush { padding: 0; overflow: hidden; }

.sec { margin-bottom: 22px; }
.sec h4 { margin: 0 0 9px; font-family: var(--mono); font-size: 9.5px; letter-spacing: .11em; text-transform: uppercase; color: var(--ink-3); }

.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: 8px; overflow: hidden; margin-bottom: 22px; }
.stat { background: var(--sheet); padding: 14px 16px; cursor: pointer; }
.stat:hover { background: var(--paper); }
.stat .v { font-family: var(--mono); font-size: 23px; font-weight: 600; letter-spacing: -.02em; margin-top: 5px; }
.stat .d { font-family: var(--mono); font-size: 10px; color: var(--ink-3); margin-top: 3px; }
.stat.alert .v { color: var(--accent); }

.matrix { width: 100%; border-collapse: collapse; background: var(--sheet); font-size: 12.5px; }
.matrix th, .matrix td { border: 1px solid var(--line); padding: 9px 12px; text-align: left; }
.matrix thead th { background: var(--paper); font-family: var(--mono); font-size: 9.5px; letter-spacing: .09em; text-transform: uppercase; color: var(--ink-2); font-weight: 500; position: sticky; top: 0; z-index: 2; }
.matrix tbody th { font-weight: 500; color: var(--ink-2); width: 250px; }
.matrix td { font-family: var(--mono); font-size: 11.5px; color: var(--ink); }
.matrix td.n { color: var(--ink-3); }
.matrix tr:hover td { background: var(--paper); }
.matrix tr.sel td { background: var(--accent-soft); }
.matrix td.editable { cursor: pointer; }
.matrix td.editable:hover { box-shadow: inset 0 0 0 1px var(--ink-3); }
.pricerow td { font-family: var(--mono); font-size: 14px; font-weight: 600; }
.note { font-size: 11.5px; color: var(--ink-3); margin-top: 12px; }

/* Queue */
.queue { flex: 1; display: flex; min-height: 0; }
.qlist { width: 340px; flex: none; border-right: 1px solid var(--line); background: var(--sheet); overflow-y: auto; }
.qi { padding: 13px 16px; border-bottom: 1px solid var(--line-2); cursor: pointer; }
.qi:hover { background: var(--paper); }
.qi.on { background: var(--paper); box-shadow: inset 2px 0 0 var(--accent); }
.qi h5 { margin: 5px 0 4px; font-size: 13.5px; font-weight: 600; line-height: 1.35; }
.qi .m { font-family: var(--mono); font-size: 9.5px; color: var(--ink-3); display: flex; gap: 10px; flex-wrap: wrap; }
.conf { display: flex; align-items: center; gap: 5px; font-family: var(--mono); font-size: 9.5px; color: var(--ink-2); }
.meter { width: 40px; height: 4px; border-radius: 2px; background: var(--line); overflow: hidden; flex: none; }
.meter b { display: block; height: 100%; background: var(--ink); }
.qdetail { flex: 1; overflow-y: auto; padding: 22px 26px 40px; min-width: 0; }
.grid2 { display: grid; grid-template-columns: 1fr 340px; gap: 26px; align-items: start; }

.quote { border-left: 2px solid var(--ink); padding: 2px 0 2px 12px; margin: 0 0 10px; font-size: 12.5px; line-height: 1.55; color: var(--ink-2); }
.quote cite { display: block; margin-top: 5px; font-family: var(--mono); font-size: 9.5px; font-style: normal; color: var(--ink-3); }
.ba { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.ba figure { margin: 0; }
.ba .mapbox { height: 118px; border: 1px solid var(--line); border-radius: 6px; overflow: hidden; position: relative; background: var(--paper); }
.ba figcaption { margin-top: 5px; font-family: var(--mono); font-size: 9px; letter-spacing: .07em; text-transform: uppercase; color: var(--ink-3); }

.fields { display: flex; flex-direction: column; gap: 11px; }
.f label { display: block; font-family: var(--mono); font-size: 9px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 4px; }
.f .val { border: 1px solid var(--line); border-radius: 5px; background: var(--sheet); padding: 8px 10px; font-size: 12.5px; }
.f .val.mono { font-family: var(--mono); font-size: 11.5px; }
.actions { display: flex; gap: 8px; margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line); flex-wrap: wrap; }

.stamp { border: 1px solid var(--line); border-radius: 7px; background: var(--sheet); padding: 14px 15px; margin-bottom: 14px; }
.stamp .g { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 10px; }
.stamp .g > * { min-width: 0; }
.warn { display: flex; gap: 9px; padding: 11px 13px; border: 1px solid var(--accent); background: var(--accent-soft); border-radius: 6px; font-size: 12px; line-height: 1.5; color: var(--accent-deep); margin-top: 12px; }
.warn b { display: block; margin-bottom: 3px; color: var(--accent); }

/* Editor */
.editor3 { display: grid; grid-template-columns: 1fr 1fr 340px; height: 100%; min-height: 0; }
.ecol { overflow-y: auto; padding: 20px; border-right: 1px solid var(--line); background: var(--sheet); }
.ecol:last-child { border-right: none; background: var(--paper); }
.emap { height: 280px; border: 1px solid var(--line); border-radius: 6px; overflow: hidden; }

/* Assistant */
.chat { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.chatlog { flex: 1; overflow-y: auto; padding: 24px; }
.msg { max-width: 760px; margin: 0 auto 22px; }
.msg .who { font-family: var(--mono); font-size: 9.5px; letter-spacing: .11em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 6px; }
.msg .content { font-size: 13.5px; line-height: 1.68; white-space: pre-wrap; color: var(--ink-2); }
.msg.user .content { background: var(--sheet); border: 1px solid var(--line); border-radius: 7px; padding: 12px 14px; color: var(--ink); }
.msg .cites { margin-top: 10px; display: flex; flex-wrap: wrap; gap: 6px; }
.chatin { border-top: 1px solid var(--line); padding: 14px 24px; background: var(--sheet); flex: none; }
.chatin .inner { max-width: 760px; margin: 0 auto; display: flex; gap: 9px; align-items: flex-end; }
.chatin textarea { min-height: 42px; max-height: 200px; }

.bars-chart { display: flex; align-items: flex-end; gap: 2px; height: 90px; }
.bars-chart .b { flex: 1; background: var(--ink); border-radius: 2px 2px 0 0; min-height: 2px; opacity: .78; }
.bars-chart .b:hover { opacity: 1; }

.status-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--ink-3); flex: none; }
.status-dot.on { background: var(--ok); box-shadow: 0 0 0 3px oklch(0.55 0.09 160 / .16); }
.status-dot.off { background: var(--warn-line); }

.settings-group { background: var(--sheet); border: 1px solid var(--line); border-radius: 8px; padding: 20px; margin-bottom: 16px; max-width: 720px; }
.settings-group > header { display: flex; align-items: center; gap: 10px; margin-bottom: 5px; }
.settings-group > header h3 { font-size: 14.5px; flex: 1; letter-spacing: -.01em; }
.settings-group > .desc { font-size: 12.5px; color: var(--ink-2); line-height: 1.55; margin-bottom: 16px; }

/* --- Auth screens --------------------------------------------------------- */
.authwrap { display: grid; place-items: center; height: 100vh; padding: 20px; background: var(--paper); }
.authcard { width: min(400px, 100%); background: var(--sheet); border: 1px solid var(--line); border-radius: 9px; padding: 26px; box-shadow: 0 8px 40px var(--shadow); }

/* --- Mobile --------------------------------------------------------------- */

.mobile-only { display: none; }

@media (max-width: 1180px) { .feed { width: 326px; } .layers { width: 214px; } .grid2 { grid-template-columns: 1fr; } .editor3 { grid-template-columns: 1fr 1fr; } }
@media (max-width: 1100px) { .topbar .hide-sm { display: none; } }
@media (max-width: 940px)  { .legend { display: none; } .plans { grid-template-columns: repeat(2, 1fr); } .plan:nth-child(2n) { border-right: none; } .stats { grid-template-columns: repeat(2, 1fr); } }

@media (max-width: 860px) {
  .mobile-only { display: inline-flex; }
  .topbar { gap: 10px; padding: 0 12px; }
  .topbar nav, .search { display: none; }
  .main { position: relative; }
  .maparea { display: block; }
  .feed {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 900; width: auto;
    height: 64vh; border-left: 0; border-top: 1px solid var(--line);
    border-radius: 13px 13px 0 0; transition: transform .22s cubic-bezier(.2,.8,.3,1);
    box-shadow: 0 -6px 28px oklch(0.17 0.006 260 / .18);
  }
  .feed.peek { transform: translateY(calc(64vh - 92px)); }
  .feed.half { transform: translateY(32vh); }
  .feed.full { transform: translateY(0); }
  .feed::before { content: ''; position: absolute; top: 6px; left: 50%; transform: translateX(-50%); width: 34px; height: 4px; border-radius: 3px; background: var(--line); }
  .feedhead { padding-top: 15px; }
  .layers { width: calc(100% - 28px); max-height: 46vh; }
  .timeline { bottom: auto; top: 14px; left: 14px; right: 14px; }
  .plans { grid-template-columns: 1fr; }
  .plan { border-right: none; border-bottom: 1px solid var(--line); }
  .editor3 { grid-template-columns: 1fr; }
  .ecol { border-right: none; border-bottom: 1px solid var(--line); }
  .queue { flex-direction: column; }
  .qlist { width: auto; max-height: 40vh; border-right: none; border-bottom: 1px solid var(--line); }
  .side { position: fixed; inset: 0 auto 0 0; z-index: 1100; transform: translateX(-100%); transition: transform .2s; }
  .side.open { transform: none; }
  .wrap { padding: 28px 16px 60px; }
  .h1 { font-size: 32px; }
  .stats { grid-template-columns: 1fr 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* Sign-out sits inside the dark sidebar, so it must not read as a primary action. */
.side .user .btn {
  background: transparent; color: oklch(0.72 0.004 260);
  border-color: oklch(0.32 0.006 260); font-size: 11.5px;
}
.side .user .btn:hover { color: var(--sheet); border-color: oklch(0.45 0.006 260); }

/* The dashboard runs eight counters, so the strip wraps rather than squeezing. */
.stats.wide { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }

/* The entitlement matrix keeps even tier columns, as the design shows, so a long
   layer list wraps inside its cell instead of stretching one column. */
.matrix { table-layout: fixed; }
.matrix thead th:first-child, .matrix tbody th { width: 250px; }
.matrix td { word-break: break-word; }

/* --- The archive ---------------------------------------------------------- */
/* A file browser: the tree on the left keeps its own scroll, so moving deep
   into a branch never pushes the folder you are reading off the screen. */
.archive { display: grid; grid-template-columns: 250px 1fr; gap: 18px; align-items: start; }
.archive-side {
  position: sticky; top: 12px; max-height: calc(100vh - 150px);
  display: flex; flex-direction: column; gap: 8px;
  border: 1px solid var(--line); border-radius: 5px; padding: 10px; background: var(--sheet);
}
.archive-tree { overflow-y: auto; min-height: 0; margin: 0 -4px; }
.archive-node, .archive-hit {
  display: flex; align-items: center; gap: 7px; width: 100%;
  padding: 4px 8px; border-radius: 4px; cursor: pointer;
  font-size: 12.5px; color: var(--ink-2); line-height: 1.35;
}
.archive-node:hover, .archive-hit:hover { background: var(--paper); color: var(--ink); }
.archive-node.on { background: var(--paper); color: var(--ink); font-weight: 500; }
.archive-ico { font-family: var(--mono); font-size: 10px; color: var(--ink-3); width: 11px; flex: none; text-align: center; }
.archive-node > span:nth-child(2), .archive-hit > span:nth-child(2) {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.archive-main { min-width: 0; }
.archive-crumb { display: flex; gap: 6px; align-items: center; font-size: 12px; margin-bottom: 12px; flex-wrap: wrap; }
.archive-crumb a { cursor: pointer; color: var(--ink-2); }
.archive-crumb a:hover { color: var(--ink); }
.archive-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 14px; margin-bottom: 16px; }
.archive-section {
  display: flex; justify-content: space-between; align-items: baseline;
  font-family: var(--mono); font-size: 9px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-3); border-bottom: 1px solid var(--line); padding-bottom: 5px; margin-bottom: 4px;
}
.archive-row {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 4px; border-bottom: 1px solid var(--line-2);
  font-size: 13px; cursor: pointer;
}
.archive-row:hover { background: var(--paper); }
.archive-row .archive-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.archive-row .btn { flex: none; }

@media (max-width: 860px) {
  .archive { grid-template-columns: 1fr; }
  .archive-side { position: static; max-height: 320px; }
}

/* --- The time bar ----------------------------------------------------------
   One Mecca day under the master map, hour by hour, with the whole record
   reachable behind the date. Clicking a bar winds the map back to the end of
   that hour; clicking the date opens the picker below. */

/* Centred and bounded rather than stretched across the whole map. Twenty-four
   bars spread over a 1400px window are fifty-pixel blocks, which reads as a bar
   chart of something rather than as a day. */
.hourstrip {
  left: 50%; right: auto;
  transform: translateX(-50%);
  width: min(760px, calc(100% - 28px)); max-width: none;
}

.timehead {
  display: flex; align-items: center; gap: 10px; margin-bottom: 7px;
}
.datebtn {
  display: inline-flex; align-items: baseline; gap: 6px; flex: none;
  padding: 3px 8px; border-radius: 5px; border: 1px solid var(--line);
  background: var(--sheet); font-size: 12.5px; font-weight: 600; color: var(--ink);
}
.datebtn i { font-style: normal; font-size: 9px; color: var(--ink-3); }
.datebtn:hover { border-color: var(--ink-3); }
.datebtn.on { border-color: var(--ink); background: var(--paper); }

/* Grid tracks rather than flex children. Every hour must occupy exactly the
   same width whatever is in it, and flex kept sizing the bars to their content
   — a busy hour came out a few pixels wide and an empty one took the slack.
   `minmax(0, 1fr)` is the form that cannot be stretched by content. */
.hourbars {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr);
  gap: 2px; height: 42px; align-items: end;
}
.hourbar {
  align-self: stretch; min-width: 0;
  display: flex; align-items: flex-end; justify-content: center;
  cursor: pointer; border-radius: 2px;
}
/* The track is a full-width hit area — an hour should be easy to click — but
   the bar drawn inside it is capped, so the strip reads as a row of marks on a
   timeline rather than as adjacent blocks. */
.hourbar > span {
  display: block; width: 100%; max-width: 17px; min-height: 2px;
  background: var(--ink-3); border-radius: 2px 2px 0 0; transition: background .12s;
}
.hourbar:hover > span { background: var(--ink); }
.hourbar.on > span { background: var(--accent); }
/* An hour with nothing in it is quiet, not broken: it keeps a baseline tick so
   the strip reads as a timeline rather than as a gap.
   Not `.empty` — that is already the "nothing here" placeholder above, and a
   bar that picked it up inherited `padding: 44px 20px`, which is why quiet
   hours came out forty pixels wide and eighty-eight tall. */
.hourbar.quiet > span { background: var(--line); }
.hourbar.quiet:hover > span { background: var(--ink-3); }
/* Hours of today that have not happened yet. Shown rather than omitted, so the
   strip is always a whole day and the six-hour marks stay where the eye
   expects them. */
.hourbar.ahead { cursor: default; }
.hourbar.ahead > span { background: var(--line-2); }
.hourbar.ahead:hover > span { background: var(--line-2); }
/* The six-hour marks live on the axis below, not through the bars: a rule
   drawn behind a bar competes with the bar for the same reading. */

.houraxis {
  position: relative; height: 12px; margin-top: 3px;
  font-family: var(--mono); font-size: 8.5px; color: var(--ink-3);
}
.houraxis span { position: absolute; transform: translateX(-50%); }
/* The ends would otherwise be half off the card. */
.houraxis span:first-child { transform: none; }
.houraxis span:last-child { transform: translateX(-100%); }

/* --- The date picker -------------------------------------------------------
   Years, then months, then a weekday grid — every date the platform holds,
   from its first record. Each day carries a bar of how busy it was, so finding
   the day something happened is reading rather than guessing. */

.datepick {
  position: absolute; left: 0; bottom: calc(100% + 9px); z-index: 40;
  width: 268px; padding: 11px 12px 9px; border-radius: 9px;
  background: var(--sheet); border: 1px solid var(--line);
  box-shadow: 0 10px 30px oklch(0.17 0.006 260 / .17);
}
.dpyears, .dpmonths {
  display: flex; flex-wrap: wrap; gap: 3px; margin-bottom: 8px;
}
.dpyears button, .dpmonths button {
  padding: 2px 7px; border-radius: 4px; font-family: var(--mono);
  font-size: 10px; letter-spacing: .03em; color: var(--ink-2);
  border: 1px solid transparent;
}
.dpmonths { padding-bottom: 8px; border-bottom: 1px solid var(--line-2); }
.dpyears button:hover, .dpmonths button:hover { background: var(--paper); }
.dpyears button.on, .dpmonths button.on { background: var(--ink); color: var(--sheet); }
/* A year or month with nothing in it is still offered — a gap in the picker
   reads as a bug, where an empty month reads as a quiet month. */
.dpyears button.quiet, .dpmonths button.quiet { color: var(--ink-3); opacity: .55; }

.dpweek, .dpgrid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.dpweek {
  margin-bottom: 3px; font-family: var(--mono); font-size: 8.5px;
  color: var(--ink-3); text-align: center;
}
.dcell {
  display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
  gap: 2px; height: 30px; padding-bottom: 3px; border-radius: 4px;
  border: 1px solid transparent; font-size: 11px; color: var(--ink-2);
}
.dcell.blank { visibility: hidden; }
.dcell:hover:not(:disabled) { background: var(--paper); }
.dcell .dnum { line-height: 1; }
.dcell .dbar { width: 14px; border-radius: 1px; background: var(--ink-3); }
.dcell.quiet .dbar { background: transparent; }
.dcell.today { border-color: var(--line); font-weight: 600; }
.dcell.on { background: var(--ink); color: var(--sheet); border-color: var(--ink); }
.dcell.on .dbar { background: var(--sheet); }
.dcell.off { opacity: .3; cursor: default; }

.dpfoot {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: 8px; padding-top: 7px; border-top: 1px solid var(--line-2);
  font-size: 10.5px; color: var(--ink-3);
}

/* --- Sites and the removal queue ------------------------------------------ */

.modal.wide { width: min(880px, 100%); }
.siteedit { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
@media (max-width: 760px) { .siteedit { grid-template-columns: 1fr; } }

/* The symbol as it appears on the map, reused in every list that names one.
   A row about a marker that does not show the marker makes the operator hold
   the mapping in their head. */
.marksym {
  display: inline-grid; place-items: center; flex: none;
  color: #fff; background: var(--c); border-radius: 999px;
}
.marksym.site {
  /* Matches .pin-site exactly, including its light ground: a legend swatch that
     does not look like the thing on the map is not a legend. */
  border-radius: 6px; color: var(--c); background: var(--map-ring);
  box-shadow: inset 0 0 0 2px var(--c);
}

/* The kind picker. Symbols rather than a dropdown, because the symbol is what
   goes on the map and a name in a list does not tell you what it will look
   like there. */
.kindpick {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(74px, 1fr));
  gap: 4px; max-height: 172px; overflow-y: auto; padding: 3px;
  border: 1px solid var(--line); border-radius: 7px; background: var(--paper);
}
.kindtile {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 7px 3px 5px; border-radius: 5px; border: 1px solid transparent;
  background: var(--sheet); color: var(--ink-2);
}
.kindtile em {
  font-style: normal; font-size: 8.5px; line-height: 1.15; text-align: center;
  color: var(--ink-3); max-width: 100%;
}
.kindtile:hover { border-color: var(--line); }
.kindtile.on { background: var(--ink); color: var(--sheet); border-color: var(--ink); }
.kindtile.on em { color: oklch(0.86 0.004 260); }

.siteswrap { display: grid; grid-template-columns: 1fr 250px; gap: 18px; align-items: start; }
@media (max-width: 1080px) { .siteswrap { grid-template-columns: 1fr; } }
.sitesbar { display: flex; gap: 8px; margin-bottom: 14px; flex-wrap: wrap; }
.sitesbar input, .sitesbar select { width: auto; }
.sitegrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(268px, 1fr)); gap: 9px; }
.sitecard {
  display: flex; align-items: center; gap: 11px; padding: 11px 12px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--sheet);
  text-align: left;
}
.sitecard:hover { border-color: var(--ink-3); }
.sitecard.closed { opacity: .55; }
.sitecard .sname { font-size: 13px; font-weight: 600; }

/* A queue row reads as a sentence: removing "this thing", for this reason. */
.removal { display: flex; align-items: center; gap: 12px; padding: 12px 14px; margin-bottom: 8px; }
.removal.done { opacity: .68; }
.rlabel { display: flex; align-items: baseline; gap: 7px; font-size: 13.5px; }
.rlabel > span:last-child { font-weight: 600; }
.rverb {
  font-family: var(--mono); font-size: 9px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--accent); flex: none;
}
.ractions { display: flex; gap: 6px; flex: none; }

/* --- Language, as a place rather than a toggle ---------------------------- */
/* Two links to the same screen, one per language. The URL carries which one
   you are reading, so it can be shared and indexed; a badge could do neither. */
.langpick { display: flex; align-items: center; gap: 2px; font-size: 11.5px; }
.langpick a {
  padding: 3px 8px; border-radius: 4px; color: var(--ink-3);
  font-family: var(--mono); letter-spacing: .04em;
}
.langpick a:hover { color: var(--ink); background: var(--sheet-2); }
.langpick a.on { color: var(--ink); background: var(--sheet-2); }
[dir="rtl"] .langpick a { letter-spacing: normal; }

/* --- The ingest feed ------------------------------------------------------ */
/* One column of everything that has come in, read the way a timeline is read:
   who said it, when, what it said, and the one action worth taking on it. */
.feedstream { display: flex; flex-direction: column; gap: 10px; max-width: 720px; }
.fitem {
  background: var(--sheet); border: 1px solid var(--line); border-radius: 8px;
  padding: 12px 14px 13px; transition: border-color .12s, opacity .2s;
}
.fitem:hover { border-color: var(--ink-3); }
.fitem.used { opacity: .45; }
.fhead { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; flex-wrap: wrap; }
.fsrc {
  font-size: 12px; font-weight: 600; color: var(--ink); padding: 0;
  border-bottom: 1px dotted var(--ink-3);
}
.fsrc:hover { color: var(--accent); border-bottom-color: var(--accent); }
.fhead .btn { margin-inline-start: auto; }
.ftext {
  font-size: 13px; line-height: 1.62; color: var(--ink-2);
  margin: 0; white-space: pre-wrap; overflow-wrap: anywhere;
}
.fmedia { display: flex; gap: 6px; margin-top: 10px; flex-wrap: wrap; }
.fmedia img {
  width: 104px; height: 78px; object-fit: cover; border-radius: 5px;
  border: 1px solid var(--line);
}
.furl {
  display: inline-block; margin-top: 9px; color: var(--ink-3);
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.furl:hover { color: var(--accent); }
.chip.tiny { font-size: 9px; padding: 0 5px; }

/* The feed's own filter row: a search that can breathe and two narrow pickers,
   rather than three controls each taking the full width of the screen. */
.feedstream, .fitem { min-width: 0; }
.filterbar select { width: auto; min-width: 130px; }

/* --- What the assistant did ----------------------------------------------- */
/* Listed under the answer, collapsed. An answer that quietly changed four
   records and mentioned two of them is the failure this exists to prevent. */
.toolcalls { margin-bottom: 10px; font-size: 12px; }
.toolcalls summary {
  cursor: pointer; color: var(--ink-3); font-family: var(--mono);
  font-size: 10.5px; letter-spacing: .05em; text-transform: uppercase;
  padding: 3px 0; list-style: none;
}
.toolcalls summary::-webkit-details-marker { display: none; }
.toolcalls summary::before { content: "▸ "; }
.toolcalls[open] summary::before { content: "▾ "; }
.toolcalls summary:hover { color: var(--ink-2); }
.toolcall {
  display: flex; gap: 9px; align-items: baseline; padding: 5px 0 5px 11px;
  border-left: 2px solid var(--line); color: var(--ink-2); line-height: 1.5;
}
.toolcall code {
  font-family: var(--mono); font-size: 10.5px; color: var(--ink-3); flex: none;
}
.toolcall span { min-width: 0; overflow-wrap: anywhere; white-space: pre-wrap; }
.toolcall.wrote { border-left-color: var(--accent); }
.toolcall.wrote code { color: var(--accent); }
.toolcall.failed { border-left-color: var(--warn-line); }
.toolcall.failed span { color: var(--warn-ink); }
.chip.acting { border-color: var(--accent); color: var(--accent); }

/* --- Territory, painted --------------------------------------------------- */
/* A brush and a map. Everything that used to be a question — confidence, an
   effective date, whether to publish — is a default, because for each one there
   is an answer that is right almost always, and a form asked four times an hour
   is what made the previous two versions of this screen unusable. */
.tbar { display: flex; gap: 11px; align-items: center; margin-bottom: 9px; }
.tcrumb { display: flex; gap: 6px; align-items: center; flex: none; }
.tsearch-results {
  position: absolute; top: 36px; left: 0; right: 0; z-index: 40; display: none;
  background: var(--sheet); border: 1px solid var(--line); border-radius: 6px;
  max-height: 280px; overflow-y: auto; box-shadow: 0 8px 26px var(--shadow);
}
.tsearch-row {
  display: flex; justify-content: space-between; gap: 10px; width: 100%;
  padding: 7px 11px; font-size: 12.5px; text-align: start; color: var(--ink);
}
.tsearch-row:hover { background: var(--sheet-2); }

.paintwrap { display: flex; gap: 13px; align-items: stretch; }
.paintside { width: 250px; flex: none; display: flex; flex-direction: column; }
.paintmain { flex: 1; min-width: 0; }
.paintmap {
  height: calc(100vh - 190px); min-height: 440px; border-radius: 7px;
  overflow: hidden; border: 1px solid var(--line); cursor: crosshair;
  /* A stroke that drags across forty districts must not select the labels on
     the way past, or the whole map ends up highlighted blue. */
  user-select: none; -webkit-user-select: none;
}

/* Who the next click gives ground to, pinned above the list that scrolls.
   Reading it off the highlighted row failed for the obvious reason: fifty
   actors do not fit, so the armed one was usually scrolled out of sight. */
.armed {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 11px; margin-bottom: 8px;
  border: 1px solid var(--line); border-left: 3px solid var(--c);
  border-radius: 6px; background: var(--sheet);
}
.armed-sw {
  width: 20px; height: 20px; border-radius: 4px; flex: none;
  background: var(--c); border: 1px solid oklch(0.17 0.006 260 / .25);
}
.armed-name {
  font-size: 13.5px; font-weight: 600; color: var(--ink); line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.brushfind { margin-bottom: 6px; font-size: 12px; }

.brushes {
  display: flex; flex-direction: column; gap: 1px;
  max-height: 38vh; overflow-y: auto;
  border: 1px solid var(--line); border-radius: 6px; padding: 3px;
  background: var(--sheet);
}

/* The way into a province's districts. It was a double-click and a line of
   tooltip text, which is to say it could not be found. */
.godeeper {
  margin-top: 14px; padding: 11px; border-radius: 6px;
  border: 1px solid var(--line); background: var(--sheet);
}

/* Buttons on this panel carry real names — "Islamic Emirate of Afghanistan",
   "Special Region of Yogyakarta" — and .btn is nowrap, so they ran straight out
   of the panel and across the map. Here they wrap instead. */
.paintside .btn-block {
  white-space: normal; text-align: start; line-height: 1.4;
  padding-top: 6px; padding-bottom: 6px;
}
.paintside .btn-block > span:first-child { min-width: 0; overflow-wrap: anywhere; }
.brush {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 5px 8px; border-radius: 4px; font-size: 12.5px;
  color: var(--ink-2); text-align: start;
}
.brush:hover { background: var(--sheet-2); color: var(--ink); }
.brush.on { background: var(--sheet-2); color: var(--ink); box-shadow: inset 2px 0 0 var(--accent); }
.brush .bsw {
  width: 13px; height: 13px; border-radius: 3px; flex: none;
  background: var(--c); border: 1px solid oklch(0.17 0.006 260 / .28);
}
.brush.special .bsw { border-radius: 999px; }
.brush .bname { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.brush .bn { font-family: var(--mono); font-size: 9.5px; color: var(--ink-3); flex: none; }
.brush.on .bn { color: var(--ink-2); }

.ttip.leaflet-tooltip {
  background: oklch(0.995 0.001 260 / .95); color: var(--ink);
  border: 1px solid var(--line); border-radius: 4px;
  font-size: 11.5px; padding: 4px 8px; box-shadow: 0 4px 14px var(--shadow);
}
.ttip.leaflet-tooltip::before { display: none; }

@media (max-width: 1100px) {
  .paintwrap { flex-direction: column; }
  .paintside { width: 100%; }
  .paintmap { height: 56vh; }
}

/* --- Data & backup -------------------------------------------------------- */
/* The rules table explains itself in prose, so its first column needs room to
   be prose rather than a column of two-word lines. */
.keeptable { table-layout: fixed; }
.keeptable td:first-child, .keeptable th:first-child { width: 52%; }
.keeptable td:nth-child(2), .keeptable th:nth-child(2) { width: 14%; }
.keeptable td:nth-child(3), .keeptable th:nth-child(3) { width: 14%; }
.keeptable td:first-child .small { font-family: var(--sans); }
/* Three tiles in a four-column grid left a grey hole where the fourth would
   be. This one sizes itself to what it holds. */
.stats.auto { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
