/*
 * What a screen is made of: a page header, then panels in order of how much
 * they matter, each with a head and its work. A panel is the one container;
 * panels never nest. As in the app, a panel is a filled card with no outline,
 * and the rows inside one are parted by space and a hover fill, never a rule.
 *
 * Every panel's head says what it is for in one plain line (.d-card-sub):
 * the operator should be able to tell what a feature does for them without
 * asking anybody.
 */

/* ── The page header: what this is, and the one thing to do here ────────── */

.d-dash,
.dk-page { display: flex; flex-direction: column; gap: var(--s-6); min-width: 0; }

/* The page head is a band, as each public page opens on one: the lettered
   title and its line on the contour lines, lit green from the corner. It is
   what makes a screen read as a page of Cite rather than a form in a box. */
.d-head,
.dk-head {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s-4) var(--s-6);
  min-height: 168px;
  padding: var(--s-8) var(--s-8) var(--s-6);
  border-radius: var(--r-4);
  background:
    radial-gradient(720px 260px at 88% -20%, color-mix(in srgb, var(--g-500) 24%, transparent), transparent 70%),
    var(--raise);
}
.d-head::before,
.dk-head::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: url('/site/topo.svg') center / cover no-repeat;
  filter: var(--topo-filter);
  opacity: var(--topo-op);
  pointer-events: none;
  -webkit-mask: linear-gradient(to right, rgba(0, 0, 0, 0.25), #000 70%);
  mask: linear-gradient(to right, rgba(0, 0, 0, 0.25), #000 70%);
}
@media (max-width: 600px) {
  .d-head,
  .dk-head { min-height: 0; padding: var(--s-6) var(--s-5) var(--s-5); }
}
.d-head > div:first-child,
.dk-head > div:first-child { min-width: 0; }
.d-title,
.dk-title,
.a-title,
.ap-title {
  color: var(--ink);
  font-size: var(--t-28);
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: -0.028em;
  text-wrap: balance;
}
.d-lede,
.dk-lede,
.ap-lede {
  max-width: 64ch;
  margin-top: var(--s-1);
  color: var(--ink-3);
  font-size: var(--t-14);
  line-height: 1.5;
  text-wrap: pretty;
}
.d-actions,
.dk-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); }
/* On a phone the actions are a block of their own under the title: the main
   one across the top, the others in an even pair under it, rather than a row
   that breaks wherever the third button stops fitting. */
@media (max-width: 600px) {
  .d-head .d-actions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); width: 100%; }
  .d-head .d-actions > * { justify-content: center; }
  .d-head .d-actions > .d-act-go,
  .d-head .d-actions > :only-child { grid-column: 1 / -1; }
  .d-head .d-actions > .d-act-go { order: -1; }
}

/* ── Panels ─────────────────────────────────────────────────────────────── */

.d-card,
.dk-panel {
  min-width: 0;
  padding: var(--s-5);
  border-radius: var(--r-4);
  background: var(--raise);
}
.d-card-head,
.dk-panel-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s-3);
  margin-bottom: var(--s-4);
}
.d-card-head h2,
.d-card-head h3,
.dk-panel-head h2 {
  color: var(--ink);
  font-size: var(--t-16);
  font-weight: 750;
  line-height: 1.3;
  letter-spacing: -0.016em;
}
.d-card-sub,
.dk-panel-sub {
  display: block;
  margin-top: 2px;
  color: var(--ink-3);
  font-size: var(--t-13);
  font-weight: 450;
  letter-spacing: 0;
}
.d-card-head > span:not(.d-card-sub):not(.v-side-tag) { color: var(--ink-3); font-size: var(--t-13); }

/* Two or three panels side by side; they stack when the column narrows. */
.d-pair,
.d-says-grid,
.dk-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-4); align-items: stretch; }
.d-grid-3,
.dk-grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-4); align-items: stretch; }
@media (max-width: 1100px) {
  .d-grid-3,
  .dk-grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 760px) {
  .d-pair,
  .d-says-grid,
  .dk-pair,
  .d-grid-3,
  .dk-grid-3 { grid-template-columns: minmax(0, 1fr); }
}

/* A list inside a panel: rows parted by space, lit under the pointer. */
.dk-rows { display: flex; flex-direction: column; gap: 2px; margin: 0 calc(-1 * var(--s-3)); }
.dk-row {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-height: 52px;
  padding: var(--s-3);
  border-radius: 12px;
  color: var(--ink);
  text-align: left;
  transition: background 0.15s var(--e-out);
}
button.dk-row,
a.dk-row { width: 100%; }
button.dk-row:hover,
a.dk-row:hover { background: var(--raise-2); text-decoration: none; }

/* An icon beside a row's text: drawn plain, in the colour it means. */
.v-glyph {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--v-c, var(--ink-2)) 14%, var(--raise-2));
  color: var(--v-c, var(--ink-2));
}
.v-glyph .ic { width: 16px; height: 16px; }

/* ── Empty, loading ─────────────────────────────────────────────────────── */

.d-empty,
.a-clear,
.dk-empty { color: var(--ink-3); font-size: var(--t-14); line-height: 1.5; }
.d-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-4) var(--s-4) var(--s-2);
  color: var(--ink-4);
  text-align: center;
}
.d-empty-state .d-empty { max-width: 36ch; }

.v-skeleton { display: flex; flex-direction: column; gap: var(--s-6); }
.v-skel {
  border-radius: var(--r-3);
  background: linear-gradient(90deg, var(--skel) 30%, var(--skel-2) 50%, var(--skel) 70%) 0 0 / 300% 100%;
  animation: dk-shimmer 1.4s linear infinite;
}
.v-skel-head { width: 40%; height: 56px; }
.v-skel-kpis { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-4); }
.v-skel-kpi { height: 104px; }
.v-skel-main { display: grid; grid-template-columns: 1.4fr 1fr; gap: var(--s-6); }
.v-skel-big { height: 280px; }
@keyframes dk-shimmer { from { background-position: 100% 0; } to { background-position: 0 0; } }
@media (max-width: 760px) {
  .v-skel-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .v-skel-main { grid-template-columns: minmax(0, 1fr); }
}

/* ── Small marks ─────────────────────────────────────────────────────────── */

.v-avatar {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 32px;
  height: 32px;
  overflow: hidden;
  border-radius: 50%;
  background: var(--raise-2);
  color: var(--ink-2);
}
.v-avatar .ic { width: 17px; height: 17px; }
.v-avatar img { width: 100%; height: 100%; object-fit: cover; }
.v-avatar-sm { width: 24px; height: 24px; }

/* A dot in a state's colour; it breathes while the state is live. */
.v-live-dot {
  position: relative;
  display: inline-block;
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--v-c, var(--st-closed));
}
.v-live-dot.is-live::after {
  content: '';
  position: absolute;
  inset: -3px;
  border-radius: 50%;
  background: var(--v-c);
  opacity: 0.35;
  animation: dk-breathe 2.4s var(--e-out) infinite;
}
@keyframes dk-breathe { 0% { transform: scale(0.6); opacity: 0.45; } 100% { transform: scale(1.8); opacity: 0; } }

.dk-badge,
.a-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 24px;
  padding: 0 10px;
  border-radius: var(--r-pill);
  background: var(--raise-2);
  color: var(--ink-2);
  font-size: var(--t-12);
  font-weight: 650;
  white-space: nowrap;
}
.dk-badge.is-ok,
.a-chip-live { background: var(--ok-soft); color: var(--ok); }
.dk-badge.is-warn,
.a-chip-warn { background: var(--warn-soft); color: var(--warn); }
.dk-badge.is-bad { background: var(--danger-soft); color: var(--danger); }
.dk-badge.is-accent { background: var(--accent-soft); color: var(--accent-text); }

/* A status message a control leaves behind. desk.js lifts each new one into
   a toast and keeps this copy for screen readers only, so nothing shifts. */
.v-notice { color: var(--ink-2); font-size: var(--t-13); line-height: 1.45; }
.v-notice:empty { display: none; }
.v-notice.dk-toasted {
  position: absolute !important;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.v-arrow { display: none; }

/* ── Maps ───────────────────────────────────────────────────────────────────
   Every live map in the tools (the console's two, the vendor's area editor)
   and every map picture (the admin's seller areas, the sponsored preview)
   follows the theme: night in dark, day in light, both drained of hue so the
   one coloured thing is what is being drawn. console-page/map.js lights the
   live ones; lib/area.js picks the picture's style.

   The Mapbox wordmark and the attribution button are taken off the map: on a
   panel this size they covered a corner of the ground being aimed at. The
   credit the data's licence asks for moves under the map instead, as
   .d-map-credit, in the smallest type the desk has.

   Mapbox's own stylesheet arrives after these (vendor loads it on demand,
   last in <head>), so every rule here is one class heavier than the one it
   answers. */
:root .mapboxgl-ctrl-logo,
:root .mapboxgl-ctrl-attrib,
:root .mapboxgl-ctrl-bottom-left,
:root .mapboxgl-ctrl-bottom-right { display: none; }

/* The zoom buttons, in the desk's materials rather than Mapbox's white box. */
:root .mapboxgl-ctrl-top-right .mapboxgl-ctrl { margin: var(--s-3) var(--s-3) 0 0; }
:root .mapboxgl-ctrl-group:not(:empty) {
  overflow: hidden;
  border-radius: var(--r-pill);
  background: var(--raise);
  box-shadow: var(--pop-shadow);
}
:root .mapboxgl-ctrl-group button { width: 36px; height: 36px; }
:root .mapboxgl-ctrl-group button + button { border-top: 0; }
:root .mapboxgl-ctrl-group button:not(:disabled):hover { background: var(--raise-2); }
[data-theme="dark"] .mapboxgl-ctrl-group .mapboxgl-ctrl-icon { filter: invert(1); }

.d-map-credit {
  margin: var(--s-2) 0 0;
  color: var(--ink-4);
  font-size: var(--t-11);
  line-height: 1.4;
  text-align: right;
}

/* A map picture drawn in both themes; the one for the other theme is never
   fetched (loading="lazy" and display: none). */
[data-theme="dark"] .d-map-pic.is-light,
:root:not([data-theme="dark"]) .d-map-pic.is-dark { display: none; }
