/* ============================================================
   شمس حلب — بياناتي
   The data page's components: the sky, the statistic blocks, the
   grouped rows, the charts, the three-step sheet and the states
   nobody usually designs (offline, loading, empty, error).
   Ported from the retired app layer (ios.css) — every rule here
   was already measured for contrast and 44px targets. Loaded only
   by bayanati.php on top of site.css.
   ============================================================ */
/* ── Card ─────────────────────────────────────────────────── */
/* The base "surface" look — card background, hairline, resting-height
   shadow — is one declaration set shared by every card-shaped block in the
   app; each selector below adds only what makes it its own shape. */
.card-x,
.rows,
.stat-x,
.chart-x,
.quick-disc {
  background: var(--app-card);
  border: var(--hairline);
  box-shadow: var(--lift-1);
}

.card-x {
  margin: 0 var(--gutter);
  padding: var(--s-5);
  border-radius: var(--r-card);
}

.card-x + .card-x { margin-top: var(--s-3); }

/* ── Grouped list — the iOS idiom, hairlines not boxes ────── */
.rows {
  margin: 0 var(--gutter);
  border-radius: var(--r-card);
  overflow: hidden;
}

.rw {
  display: grid;
  grid-template-columns: 38px minmax(0, 1fr) minmax(auto, 44%);
  gap: var(--s-4);
  align-items: center;
  width: 100%;
  min-height: 60px;
  padding: var(--s-3) var(--s-4);
  background: none;
  border: none;
  text-align: start;
  text-decoration: none;
  color: var(--text);
  font-family: var(--font-app);
  font-size: var(--t-body);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  position: relative;
  transition: background-color var(--tap) var(--out);
}

/* Inset separator: starts after the icon column, the way a native
   list does. A full-width rule looks like a table. */
.rw:not(:last-child)::after {
  content: "";
  position: absolute;
  inset-block-end: 0;
  inset-inline-start: calc(var(--s-4) + 38px + var(--s-4));
  inset-inline-end: 0;
  height: 0.5px;
  background: rgba(28, 25, 23, 0.09);
}

:root[data-theme="night"] .rw:not(:last-child)::after {
  background: rgba(255, 255, 255, 0.09);
}

.rw:active { background: color-mix(in srgb, var(--text) 5%, transparent); }

.rw-ic,
.choice-ic {
  border-radius: var(--r-tile);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--tile);
  color: var(--ink);
}

.rw-ic { width: 38px; height: 38px; }

.rw-tx { min-width: 0; }

.rw-tx b {
  display: block;
  font-size: var(--t-body);
  font-weight: var(--w-medium);
  line-height: var(--lh-snug);
}

.rw-tx span {
  display: block;
  font-size: var(--t-caption);
  font-weight: 400;
  color: var(--text-muted);
  line-height: var(--lh-snug);
  margin-top: 1px;
}

.rw-end {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--s-2);
  color: var(--text-muted);
  font-size: var(--t-footnote);
  text-align: end;
}

.rw-val {
  font-weight: var(--w-strong);
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.rw-go { color: rgba(28, 25, 23, 0.25); display: flex; }
:root[data-theme="night"] .rw-go { color: rgba(255, 255, 255, 0.3); }

/* ── Buttons ──────────────────────────────────────────────────
   Four real states, not one. A button that has no pressed, loading,
   disabled and done state is a picture of a button. */
.btn-x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  width: 100%;
  min-height: 54px;
  padding: 0 var(--s-5);
  border: none;
  border-radius: var(--r-control);
  background: var(--app-accent);
  color: var(--brand-contrast);
  font-family: var(--font-app);
  font-size: var(--t-body);
  font-weight: var(--w-strong);
  cursor: pointer;
  position: relative;
  overflow: hidden;
  -webkit-tap-highlight-color: transparent;
  transition: transform var(--tap) var(--spring),
              background-color var(--move) var(--out),
              opacity var(--move) var(--out);
}

.btn-x:active { transform: scale(0.975); }

.btn-x[disabled] {
  opacity: 0.4;
  cursor: not-allowed;
  transform: none;
}

.btn-x--quiet {
  background: var(--tile);
  color: var(--ink);
}

.btn-x--plain {
  background: transparent;
  color: var(--ink);
  min-height: 48px;
}

.btn-x--danger { background: var(--bad); color: #FFFFFF; }

.btn-x.is-loading { pointer-events: none; }
.btn-x.is-loading .btn-label { opacity: 0; }

.btn-spin {
  position: absolute;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 2.5px solid color-mix(in srgb, var(--brand-contrast) 30%, transparent);
  border-top-color: var(--brand-contrast);
  opacity: 0;
  animation: spin 700ms linear infinite;
}

.btn-x.is-loading .btn-spin { opacity: 1; }

@keyframes spin { to { transform: rotate(360deg); } }

.btn-x.is-done { background: var(--ok); }
.btn-x.is-done .btn-label { opacity: 1; }

.btn-stack {
  padding: var(--s-5) var(--gutter) 0;
  display: grid;
  gap: var(--s-2);
}








/* ── Stat pair ────────────────────────────────────────────── */
/* ── Status pill — icon + word + colour, never colour alone ── */
.pill-x {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px var(--s-3);
  border-radius: var(--r-chip);
  font-size: var(--t-caption);
  font-weight: var(--w-medium);
  line-height: 1.4;
}

.pill-ok   { background: var(--ok-bg);   color: var(--ok); }
.pill-warn { background: var(--warn-bg); color: var(--warn); }
.pill-bad  { background: var(--bad-bg);  color: var(--bad); }
.pill-mute { background: color-mix(in srgb, var(--text) 8%, transparent); color: var(--text-muted); }

/* ── Segmented control ────────────────────────────────────── */
/* ── Fields ───────────────────────────────────────────────── */
.field-x { margin: 0 var(--gutter) var(--s-4); }

.field-x > label {
  display: block;
  font-size: var(--t-footnote);
  font-weight: var(--w-medium);
  margin-bottom: var(--s-2);
}

.field-x .hint {
  font-size: var(--t-caption);
  color: var(--text-muted);
  line-height: var(--lh-snug);
  margin-top: var(--s-2);
}

.input-x {
  width: 100%;
  min-height: 54px;
  padding: 0 var(--s-4);
  border: 1px solid transparent;
  border-radius: var(--r-control);
  background: var(--app-card);
  box-shadow: inset 0 0 0 0.5px rgba(28, 25, 23, 0.14);
  color: var(--text);
  font-family: var(--font-app);
  font-size: var(--t-body);
  font-variant-numeric: tabular-nums;
  transition: box-shadow var(--move) var(--out);
}

:root[data-theme="night"] .input-x {
  box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.16);
}

/* Chrome's spinner arrows sit on top of the value, are far below a
   comfortable target size, and do nothing on a phone. */
.input-x::-webkit-outer-spin-button,
.input-x::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.input-x[type="number"] { -moz-appearance: textfield; appearance: textfield; }

.input-x:focus {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--ink);
}

.field-x.is-error .input-x { box-shadow: inset 0 0 0 2px var(--bad); }

.field-error {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--t-caption);
  color: var(--bad);
  margin-top: var(--s-2);
}

/* ── Choice cards — big, one tap, no ambiguity ────────────── */
.choices { display: grid; gap: var(--s-2); margin: 0 var(--gutter); }

.choice {
  display: grid;
  grid-template-columns: 44px 1fr 24px;
  gap: var(--s-4);
  align-items: center;
  min-height: 72px;
  padding: var(--s-4);
  border-radius: var(--r-card);
  background: var(--app-card);
  border: 1.5px solid transparent;
  /* --inset-hairline already flips value under [data-theme="night"], so
     unlike the old hand-written rgba this needs no separate night override. */
  box-shadow: var(--inset-hairline), var(--lift-1);
  font-family: var(--font-app);
  text-align: start;
  color: var(--text);
  cursor: pointer;
  transition: transform var(--tap) var(--spring), border-color var(--move) var(--out),
              box-shadow var(--move) var(--out);
}

.choice:active { transform: scale(0.985); }

.choice[aria-checked="true"] {
  border-color: var(--ink);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ink) 10%, transparent), var(--lift-2);
}

.choice-tx b { display: block; font-size: var(--t-body); font-weight: 500; line-height: var(--lh-snug); }
.choice-tx > span { display: block; font-size: var(--t-caption); color: var(--text-muted); margin-top: 2px; }

.choice-ic { width: 44px; height: 44px; }

/* The tick is drawn, not just coloured — status never rests on hue. */
.choice-tick {
  width: 24px; height: 24px;
  border-radius: 50%;
  border: 1.5px solid var(--line-strong);
  display: flex; align-items: center; justify-content: center;
  color: transparent;
  transition: background-color var(--move) var(--out), border-color var(--move) var(--out),
              color var(--move) var(--out);
}

.choice[aria-checked="true"] .choice-tick {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--brand-contrast);
}

/* ── Sheet ────────────────────────────────────────────────────
   Drag-to-dismiss, the iOS spring curve, and a scrim that blurs the
   app behind it rather than just dimming it. */
.sheet-x {
  position: absolute;
  inset: 0;
  z-index: 80;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  pointer-events: none;
}

.sheet-x[hidden] { display: none; }

.sheet-scrim {
  position: absolute;
  inset: 0;
  background: rgba(20, 16, 12, 0.32);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity var(--panel) var(--spring);
}

.sheet-card {
  position: relative;
  width: 100%;
  max-height: 90%;
  display: flex;
  flex-direction: column;
  background: var(--app-ground);
  border-radius: var(--r-sheet) var(--r-sheet) 0 0;
  box-shadow: var(--lift-sheet);
  transform: translateY(100%);
  transition: transform var(--panel) var(--spring);
  pointer-events: auto;
  padding-bottom: env(safe-area-inset-bottom, 0px);
}

.sheet-x.is-open { pointer-events: auto; }
.sheet-x.is-open .sheet-scrim { opacity: 1; }
.sheet-x.is-open .sheet-card { transform: translateY(0); }

.sheet-x.is-dragging .sheet-card { transition: none; }

.sheet-grab {
  flex: 0 0 auto;
  padding: var(--s-3) 0 var(--s-2);
  display: flex;
  justify-content: center;
  cursor: grab;
  touch-action: none;
}

.sheet-grab::before {
  content: "";
  width: 36px;
  height: 5px;
  border-radius: 999px;
  background: rgba(28, 25, 23, 0.18);
}

:root[data-theme="night"] .sheet-grab::before { background: rgba(255, 255, 255, 0.22); }

.sheet-head {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding: 0 var(--s-3) var(--s-3);
  min-height: 44px;
}

.sheet-head h2 {
  flex: 1;
  text-align: center;
  font-size: var(--t-headline);
  font-weight: var(--w-strong);
  line-height: var(--lh-tight);
}

.sheet-body {
  flex: 1 1 auto;
  overflow-y: auto;
  /* A sheet scrolls one way. Sub-pixel rounding on a two-column chip grid
     was enough to put a horizontal scrollbar under the appliances. */
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  padding-bottom: var(--s-6);
}

/* .flow-foot lived here — a sticky footer inside the scrolling body. The
   step footer is outside the scroll entirely now, so it cannot be scrolled
   past at all. */

/* The tab bar lived here. There are no tabs: the app is one page. */

/* ── Connection banner ────────────────────────────────────────
   Informative, not alarming: it states the fact and what still
   works, and it never covers content. */
.conn {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin: 0 var(--gutter) var(--s-3);
  padding: var(--s-3) var(--s-4);
  border-radius: var(--r-control);
  background: var(--warn-bg);
  color: var(--warn);
  font-size: var(--t-caption);
  line-height: var(--lh-snug);
  animation: drop var(--move) var(--out) both;
}

.conn[hidden] { display: none; }

@keyframes drop {
  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: none; }
}

/* ── Skeletons ────────────────────────────────────────────────
   A shimmer that suggests the shape of what is coming, so the first
   frame is never a blank rectangle. */
.sk {
  border-radius: 8px;
  background: linear-gradient(
    100deg,
    color-mix(in srgb, var(--text) 7%, transparent) 30%,
    color-mix(in srgb, var(--text) 12%, transparent) 50%,
    color-mix(in srgb, var(--text) 7%, transparent) 70%);
  background-size: 240% 100%;
  animation: sweep 1.4s ease-in-out infinite;
}

@keyframes sweep {
  from { background-position: 100% 0; }
  to { background-position: -140% 0; }
}

.sk-line { height: 13px; margin-bottom: var(--s-2); }
.sk-line:last-child { margin-bottom: 0; }

/* ── Empty / error state ─────────────────────────────────────
   Designed, not forgotten: a mark, a plain sentence about what is
   there, and one obvious way forward. */
.state-x {
  padding: var(--s-12) var(--s-8);
  text-align: center;
}

.state-mark {
  width: 64px;
  height: 64px;
  margin: 0 auto var(--s-5);
  border-radius: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: color-mix(in srgb, var(--text) 6%, transparent);
  color: var(--text-muted);
}

.state-x.is-bad .state-mark { background: var(--bad-bg); color: var(--bad); }

.state-x h2,
.state-x h3 {
  font-size: var(--t-headline);
  font-weight: var(--w-strong);
  line-height: var(--lh-tight);
  margin-bottom: var(--s-2);
}

.state-x p {
  font-size: var(--t-footnote);
  color: var(--text-muted);
  line-height: var(--lh-body);
  max-width: 30ch;
  margin: 0 auto var(--s-6);
}

/* ── Success ──────────────────────────────────────────────────
   The tick draws itself once. One moment of delight, then it stops. */
.done-mark {
  width: 84px;
  height: 84px;
  margin: 0 auto var(--s-6);
  border-radius: 50%;
  background: var(--ok-bg);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ok);
  animation: pop 520ms var(--spring) both;
}

@keyframes pop {
  0% { transform: scale(0.6); opacity: 0; }
  60% { transform: scale(1.04); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

.done-mark .icon path,
.done-mark .icon polyline { stroke-dasharray: 40; stroke-dashoffset: 40; animation: draw 420ms 200ms var(--out) forwards; }

@keyframes draw { to { stroke-dashoffset: 0; } }

/* The screen-enter animation lived here, replaying on every tab switch.
   With one page there is nothing to transition between. */

/* ── Progress ─────────────────────────────────────────────── */


/* ── Toast ────────────────────────────────────────────────── */
.toast-x {
  position: absolute;
  inset-block-end: calc(64px + env(safe-area-inset-bottom, 0px));
  inset-inline: var(--gutter);
  z-index: 90;
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  border-radius: var(--r-control);
  background: var(--surface-inverse);
  color: var(--app-ground);
  font-size: var(--t-footnote);
  box-shadow: var(--lift-3);
  opacity: 0;
  transform: translateY(12px);
  pointer-events: none;
  transition: opacity var(--move) var(--out), transform var(--move) var(--spring);
}

.toast-x.is-on { opacity: 1; transform: none; }

/* ── Notes ────────────────────────────────────────────────── */
.note-x {
  margin: var(--s-4) var(--gutter) 0;
  font-size: var(--t-caption);
  color: var(--text-muted);
  line-height: var(--lh-body);
}

.note-tight { margin-top: var(--s-2); }
.note-center { text-align: center; }

.hairline-top { border-top: var(--hairline); }

/* ── Reduced motion ───────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .sk { animation: none; }
  .done-mark, .conn { animation: none; }
  .step-panel { animation: none; }
  .done-mark .icon path, .done-mark .icon polyline { stroke-dashoffset: 0; animation: none; }
}

/* ============================================================
   Part two — the pieces this app needs that a generic system
   would not have: the sky, the cover, the alert, the flow.
   ============================================================ */

/* ── The sky over Aleppo ──────────────────────────────────────
   Inset and rounded rather than full-bleed. A full-bleed band is
   what a website does; a card with a radius reads as a *thing* you
   own, which is the whole difference between the two. */
/* ── The hero ─────────────────────────────────────────────────
   ONE opening image, not three. This used to be a live sky card,
   then a drawn rooftop card, then a gauge card — three "today"
   visuals stacked before the reader reached a single action. The
   sky is the one that's actually live (it tracks the real sun over
   Aleppo), so it stays and absorbs the other two: today's figure
   sets inside it at display size, with the efficiency reading as a
   quiet line beneath. The drawn rooftop is no loss — sky.js already
   paints an Aleppo roofline, water tanks and dishes into this canvas. */
.sky-x {
  position: relative;
  margin: 0 var(--gutter);
  /* min-height, not height: at the largest text setting the reading below
     grows, and a fixed box would let it climb over the clock. The card
     grows instead, and the sky grows with it. */
  min-height: 470px;
  border-radius: var(--r-card);
  overflow: hidden;
  background: #1B2A52;
  box-shadow: var(--lift-2);
  isolation: isolate;
}

/* The whole hero is one tap target into the detail sheet — progressive
   disclosure, so the charts don't have to live on the home screen. */
.sky-x[role="button"] { cursor: pointer; -webkit-tap-highlight-color: transparent; }
.sky-x[role="button"]:active { transform: scale(0.994); }
.sky-x { transition: transform var(--tap) var(--spring); }

.sky-x canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

/* The reading sits on a frosted plate, not on a scrim over the whole card.
   A full-height scrim is the only way to guarantee white text over a live
   image, and it costs you the image: at the opacity daylight actually needs
   (measured: 0.86 to clear 4.5:1 on a bright sky) it erases most of what is
   painted underneath. A plate covers only the words. Measured across six
   phases of the day rather than eyeballed — clear noon was the worst case at
   2.16:1 before this, and every line clears its threshold after it. */
.sky-face {
  position: absolute;
  inset-inline: var(--s-3);
  inset-block-end: var(--s-3);
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  padding: var(--s-4) var(--s-5) var(--s-3);
  border-radius: calc(var(--r-card) - 8px);
  background: rgba(11, 9, 7, 0.60);
  /* The hairline is what makes this read as a pane of glass laid on the
     picture rather than as the picture being cropped. */
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14), 0 8px 28px rgba(0, 0, 0, 0.28);
  -webkit-backdrop-filter: blur(22px) saturate(1.35);
  backdrop-filter: blur(22px) saturate(1.35);
  color: #FFFFFF;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.45);
}

.sky-top {
  position: absolute;
  inset-block-start: var(--s-3);
  inset-inline: var(--s-3);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-2);
}

/* Darkened, not lightened. A white-tinted chip reads beautifully against a
   night sky and fails outright against the midday one — white on Aleppo's
   noon blue measures 3.4:1. Dark glass plus a hairline works in every phase. */
.sky-clock {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px var(--s-3);
  border-radius: var(--r-chip);
  background: rgba(10, 8, 6, 0.46);
  box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.22);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  font-size: var(--t-caption);
  font-weight: var(--w-medium);
  font-variant-numeric: tabular-nums;
  color: #FFFFFF;
}

/* The label above the figure. Small, quiet, and never competing —
   its whole job is to say what the big number means. */
.sky-kicker {
  font-size: var(--t-caption);
  font-weight: var(--w-medium);
  letter-spacing: 0.3px;
  color: rgba(255, 255, 255, 0.72);
}

/* THE figure. This is the one number the home screen exists to tell
   you, so it is allowed to be genuinely large — 64px against 15px
   supporting text is the contrast that makes a screen feel composed
   rather than merely populated. Optical alignment matters at this
   size: tabular numerals stop the figure jittering as it updates. */
.sky-figure {
  display: flex;
  align-items: baseline;
  gap: var(--s-2);
  font-size: var(--t-display);
  font-weight: var(--w-strong);
  line-height: var(--lh-tight);
  letter-spacing: -2.5px;
  font-variant-numeric: tabular-nums;
}

.sky-figure small {
  font-size: var(--t-headline);
  font-weight: var(--w-body);
  letter-spacing: 0;
  color: rgba(255, 255, 255, 0.78);
}

.sky-word {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  margin-top: var(--s-2);
  font-size: var(--t-footnote);
  font-weight: var(--w-body);
  line-height: var(--lh-snug);
  color: rgba(255, 255, 255, 0.9);
}

/* The icon stays on the first line when the sentence wraps. */
.sky-word .icon { flex: 0 0 auto; margin-top: 2px; }

.sky-ends {
  display: flex;
  gap: var(--s-5);
  margin-top: var(--s-3);
  padding-top: var(--s-3);
  border-top: 0.5px solid rgba(255, 255, 255, 0.16);
  font-size: var(--t-caption);
  color: rgba(255, 255, 255, 0.78);
  font-variant-numeric: tabular-nums;
}

.sky-ends i { font-style: normal; opacity: 0.75; margin-inline-end: 5px; }

/* The three-slide onboarding cover lived here. A first open goes straight
   to the first question now — there is nothing to sit through. */

/* ── Alert ────────────────────────────────────────────────────
   The native centred alert, because a destructive action must not be
   reachable by the same gesture that dismisses a sheet. */
.alert-x {
  position: absolute;
  inset: 0;
  z-index: 95;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s-8);
  pointer-events: none;
}

.alert-x[hidden] { display: none; }

.alert-scrim {
  position: absolute;
  inset: 0;
  background: rgba(20, 16, 12, 0.34);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity var(--move) var(--out);
}

.alert-card {
  position: relative;
  width: 100%;
  max-width: 300px;
  border-radius: 22px;
  background: var(--app-card);
  box-shadow: var(--lift-3);
  overflow: hidden;
  text-align: center;
  transform: scale(0.86);
  opacity: 0;
  transition: transform var(--move) var(--spring), opacity var(--move) var(--out);
  pointer-events: auto;
}

.alert-x.is-open { pointer-events: auto; }
.alert-x.is-open .alert-scrim { opacity: 1; }
.alert-x.is-open .alert-card { transform: scale(1); opacity: 1; }

.alert-body { padding: var(--s-6) var(--s-5) var(--s-5); }

.alert-body h3 {
  font-size: var(--t-headline);
  font-weight: var(--w-strong);
  line-height: var(--lh-tight);
  margin-bottom: var(--s-2);
}

.alert-body p {
  font-size: var(--t-footnote);
  color: var(--text-muted);
  line-height: var(--lh-snug);
}

.alert-acts { display: grid; }

.alert-acts button {
  min-height: 52px;
  border: none;
  border-top: 0.5px solid rgba(28, 25, 23, 0.12);
  background: transparent;
  color: var(--ink);
  font-family: var(--font-app);
  font-size: var(--t-body);
  font-weight: var(--w-body);
  cursor: pointer;
}

:root[data-theme="night"] .alert-acts button { border-top-color: rgba(255, 255, 255, 0.12); }

.alert-acts button:active { background: color-mix(in srgb, var(--text) 6%, transparent); }
.alert-acts .is-go { font-weight: var(--w-strong); }
.alert-acts .is-danger { color: var(--bad); font-weight: var(--w-strong); }

/* ── Appliance chips ─────────────────────────────────────────
   A grid, because 20 items as full-width rows is a scroll marathon.
   Each is still 64px tall and takes a whole tap. */
.chip-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-2);
  margin: 0 var(--gutter);
}

.chip-x {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 2px;
  min-height: 76px;
  padding: var(--s-3) var(--s-4);
  border-radius: var(--r-tile);
  border: 1.5px solid transparent;
  background: var(--app-card);
  box-shadow: var(--inset-hairline);
  font-family: var(--font-app);
  text-align: start;
  color: var(--text);
  cursor: pointer;
  transition: transform var(--tap) var(--spring), border-color var(--move) var(--out),
              box-shadow var(--move) var(--out), background-color var(--move) var(--out);
}

.chip-x:active { transform: scale(0.97); }

.chip-x > b {
  font-size: var(--t-footnote);
  font-weight: var(--w-medium);
  line-height: var(--lh-snug);
  /* Room for the tick, reserved whether or not it is showing — otherwise
     the label reflows the instant you tap it. */
  padding-inline-end: 24px;
}

.chip-w {
  font-size: var(--t-caption);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

.chip-x[aria-checked="true"] {
  border-color: var(--ink);
  background: color-mix(in srgb, var(--ink) 4%, var(--app-card));
  box-shadow: none;
}

/* A drawn tick in the corner — the border colour alone would be the
   one thing this app has promised never to rely on. */
.chip-mark {
  position: absolute;
  inset-block-start: 8px;
  inset-inline-end: 8px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--ink);
  color: var(--app-card);
  opacity: 0;
  transform: scale(0.5);
  transition: opacity var(--move) var(--out), transform var(--move) var(--spring);
}

.chip-x[aria-checked="true"] .chip-mark { opacity: 1; transform: scale(1); }

.chip-qty {
  display: none;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-2);
  margin-top: var(--s-3);
  font-size: var(--t-caption);
  color: var(--text-muted);
}

.chip-x[aria-checked="true"] .chip-qty { display: flex; }

/* These were 32px — under the floor, on the first screen anyone touches,
   and the two of them sit a few millimetres apart inside a chip. A hand that
   shakes needs the full 44. */
.qty-btn {
  width: var(--hit-min);
  height: var(--hit-min);
  border-radius: 50%;
  border: none;
  background: var(--tile);
  color: var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.qty-btn:active { transform: scale(0.9); }
.qty-n { min-width: 28px; font-size: var(--t-body); text-align: center; font-weight: var(--w-strong); color: var(--text); }

/* ── Flow ────────────────────────────────────────────────────── */
.flow-q {
  padding: 0 var(--gutter) var(--s-4);
}

.flow-q h3 {
  font-size: var(--t-title);
  font-weight: var(--w-strong);
  line-height: var(--lh-tight);
  letter-spacing: -0.4px;
  margin-bottom: var(--s-2);
}

.flow-q p {
  font-size: var(--t-footnote);
  color: var(--text-muted);
  line-height: var(--lh-snug);
}

/* The running total sits above the buttons and updates as you tap, so
   the answer is never a surprise at the end. */
.flow-tally {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
  margin: var(--s-5) var(--gutter) 0;
  padding: var(--s-3) var(--s-4);
  border-radius: var(--r-control);
  background: var(--tile);
  font-size: var(--t-footnote);
  color: var(--ink);
}

.flow-tally b { font-size: var(--t-headline); font-weight: var(--w-strong); font-variant-numeric: tabular-nums; }

/* .res-big / .res-head lived here — the live answer inside the entry
   sheet. The answer is the page now. */

/* ── Quick grid ──────────────────────────────────────────────── */
/* ── Charts ──────────────────────────────────────────────────── */
.chart-x {
  margin: 0 var(--gutter) var(--s-3);
  padding: var(--s-5) var(--s-4) var(--s-4);
  border-radius: var(--r-card);
}

.chart-x header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
  padding: 0 var(--s-1) var(--s-1);
}

.chart-x header b { font-size: var(--t-body); font-weight: var(--w-strong); }

.chart-x header span {
  font-size: var(--t-footnote);
  font-weight: var(--w-strong);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.chart-x > p {
  padding: 0 var(--s-1) var(--s-4);
  font-size: var(--t-caption);
  color: var(--text-muted);
  line-height: var(--lh-snug);
}

.chart-plot { height: 150px; }
.chart-plot canvas { display: block; width: 100%; height: 100%; }
.chart-plot--short { height: 62px; }

.chart-keys {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-4);
  padding: var(--s-3) var(--s-1) 0;
  font-size: var(--t-caption);
  color: var(--text-muted);
}

.chart-keys span { display: inline-flex; align-items: center; gap: 6px; }
.chart-keys i { width: 10px; height: 10px; border-radius: 3px; flex: 0 0 auto; }

/* ── Help ────────────────────────────────────────────────────── */
/* ── Danger zone ─────────────────────────────────────────────── */
.danger-note {
  margin: var(--s-3) var(--gutter) 0;
  font-size: var(--t-caption);
  color: var(--text-muted);
  line-height: var(--lh-snug);
}

/* ── Notification row ────────────────────────────────────────── */
/* ── Utilities ────────────────────────────────────────────────
   A short, closed list. Everything else is a component — this is
   what stops the app growing a second, accidental design system in
   inline style attributes. */
.k-ok  { background: var(--brand); }
.k-bad { background: var(--bad); }

/* No !important needed: this rule already sits later in the cascade than
   the base .rw-ic rule at equal specificity, so it wins on its own. */
.rw-ic--bad { background: var(--bad-bg); color: var(--bad); }
.rw-tx--bad b { color: var(--bad); }
.rw--static { cursor: default; }

.nav-spacer { width: 44px; flex: 0 0 auto; }
.has-dot { position: relative; }

.btn-mid { max-width: 260px; margin-inline: auto; }
.pad-top { margin-top: var(--s-6); }

.sk-block { height: 150px; margin-top: var(--s-4); border-radius: 12px; }
.sk-w40 { width: 40%; }

/* The chip is a checkbox, not a button, because it holds buttons of its
   own. Everything a <button> gave us for free is restored explicitly. */
/* Focus ring comes from base.css's global :focus-visible rule — this used
   to restate it identically (just to reach a role="checkbox" div), which
   only meant the chip's own border-radius stopped applying to its ring. */
.chip-x { -webkit-tap-highlight-color: transparent; user-select: none; }

.warn-p {
  margin-top: var(--s-3);
  font-size: var(--t-footnote);
  line-height: var(--lh-body);
  color: var(--text-muted);
}

/* ============================================================
   Live tracking — the hero illustration, the estimate gauge, and
   the energy-flow diagram. All three exist to make an estimate
   FEEL alive without pretending it's a real device reading — the
   honesty caption on each one is real DOM text, not a canvas pixel,
   so a screen reader hears the same disclosure a sighted reader sees.
   ============================================================ */

/* ── Hero illustration — a drawn Aleppo roofline, not a photo ── */






/* Illustration colours read from the same semantic tokens the rest of the
   app themes with — never --sand-*, which are fixed primitives that do NOT
   redefine under night mode, unlike --line/--text-muted/--brand-ink here. */

/* ── Estimate gauge ───────────────────────────────────────────
   Canvas draws only the ring; the number is real text laid over it,
   so it inherits Arabic-digit and text-size handling for free and
   reads correctly to a screen reader (the canvas itself is
   aria-hidden — see the icon()/aria-label split already used for
   every other decorative canvas in this app). */
.est-gauge-card {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  margin: 0 var(--gutter);
  padding: var(--s-4);
  border-radius: var(--r-card);
  background: var(--app-card);
  border: var(--hairline);
  box-shadow: var(--lift-1);
}

.est-gauge-wrap {
  position: relative;
  flex: 0 0 auto;
  /* The ring has to grow with the number inside it. Pinned at 88px, the
     figure outgrew its own ring at the largest text setting — the reader
     who most needs big type got the one broken layout. */
  width: calc(88px * var(--type-scale));
  height: calc(88px * var(--type-scale));
}

.est-gauge-wrap canvas { display: block; width: 100%; height: 100%; }

.est-gauge-over {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 1px;
}

.est-gauge-over b {
  font-size: var(--t-title);
  font-weight: 700;
  color: var(--text);
  letter-spacing: -0.5px;
  font-variant-numeric: tabular-nums;
}

.est-gauge-over small { font-size: var(--t-footnote); color: var(--text-muted); }

.est-gauge-tx { min-width: 0; }

.est-gauge-tx b {
  display: block;
  font-size: var(--t-body);
  font-weight: var(--w-medium);
  margin-bottom: 2px;
}

.est-gauge-tx span {
  display: block;
  font-size: var(--t-caption);
  color: var(--text-muted);
  line-height: var(--lh-snug);
}

/* ── Energy-flow diagram ──────────────────────────────────────
   Deliberately named .est-*, not .flow-* — .flow-* already belongs
   to the appliance-entry screen's question/tally/footer primitives
   elsewhere in this file, and this is an unrelated picture of where
   power goes, not a step in a form. */
.est-flow-card {
  margin: var(--s-3) var(--gutter) 0;
  padding: var(--s-5) var(--s-4) var(--s-4);
  border-radius: var(--r-card);
  background: var(--app-card);
  border: var(--hairline);
  box-shadow: var(--lift-1);
}

.est-flow-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
  padding: 0 var(--s-1) var(--s-2);
}

.est-flow-head b { font-size: var(--t-body); font-weight: var(--w-strong); }

.est-flow-canvas-wrap { height: 172px; }
.est-flow-canvas-wrap canvas { display: block; width: 100%; height: 100%; }

.est-flow-note {
  margin-top: var(--s-1);
  text-align: center;
  font-size: var(--t-caption);
  color: var(--text-muted);
  line-height: var(--lh-snug);
}

/* ── Hero affordance + the bare gauge ─────────────────────────
   The chevron that says the hero is a door, and the modifier that
   lets the gauge sit INSIDE the system card instead of being its
   own card — cards nested in cards is the fastest way to make a
   screen look busy without adding a single new idea. */
.sky-more {
  margin-inline-start: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  /* A real button, so it gets a real target — 44px is the floor, and it
     stays visually a chevron by keeping the box transparent. */
  width: 44px;
  height: 44px;
  margin-block: -12px;
  border: none;
  background: none;
  color: #FFFFFF;
  opacity: 0.75;
  cursor: pointer;
}
.sky-more:active { opacity: 1; }
.sky-ends { align-items: center; }

.est-gauge-card--bare {
  margin: 0;
  padding: var(--s-4) var(--s-4) var(--s-5);
  background: none;
  border: 0;
  box-shadow: none;
}

/* ═══════════════════════════════════════════════════════════════
   THE PAGE — everything the engine knows, on one scroll
   ═══════════════════════════════════════════════════════════════
   Ranked, not flat. Three figures carry the answer at the top; the
   rest sit in labelled sections, each one editable from its own
   heading. Nothing is behind a tap except prose.
   ─────────────────────────────────────────────────────────────── */

.data-page { padding-bottom: var(--s-12); }

/* ── The headline ─────────────────────────────────────────────
   One accent on the whole page, and it is here: the kilowatt figure
   is the answer to the question the app exists to answer. */
.pg-head {
  margin: var(--s-5) var(--gutter) var(--s-6);
  padding: var(--s-6);
  border-radius: var(--r-card);
  background: var(--app-card);
  box-shadow: var(--lift-1);
  text-align: center;
}

.pg-head-t {
  margin: 0;
  font-size: var(--t-headline);
  font-weight: var(--w-medium);
  color: var(--text-muted);
}

.pg-head-lead {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: var(--s-2);
  margin: var(--s-2) 0 0;
  color: var(--brand-ink);
  line-height: var(--lh-tight);
}
.pg-big   { font-size: var(--t-display); font-weight: var(--w-strong); letter-spacing: -3px; font-variant-numeric: tabular-nums; }
.pg-big-u { font-size: var(--t-headline); font-weight: var(--w-medium); }

.pg-head-sub {
  margin: var(--s-2) 0 var(--s-6);
  font-size: var(--t-footnote);
  color: var(--text-muted);
}

/* The two supporting figures. Large, but ink — a page with three
   accents has none. */
.pg-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-4);
  padding-top: var(--s-5);
  border-top: var(--hairline);
}
.pg-pair-cell { display: flex; flex-direction: column; gap: 4px; }
.pg-pair-l { font-size: var(--t-caption); color: var(--text-muted); }
.pg-pair-v {
  font-size: var(--t-title);
  font-weight: var(--w-strong);
  color: var(--text);
  line-height: var(--lh-tight);
  font-variant-numeric: tabular-nums;
}

/* ── Sections ─────────────────────────────────────────────────
   scroll-margin so an edit lands with the heading clear of the nav. */
.pg-sec { scroll-margin-block-start: var(--s-4); }

.pg-sec-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
  padding: var(--section) var(--gutter) var(--s-3);
}
.pg-sec-head h2 {
  margin: 0;
  font-size: var(--t-headline);
  font-weight: var(--w-strong);
  color: var(--text);
}

/* «عدّل» is a word, not a pencil. Three unlabelled pencils down one
   page is three guesses. */
.pg-edit {
  flex: 0 0 auto;
  min-height: var(--hit-min);
  padding-inline: var(--s-3);
  border: none;
  background: none;
  font-family: inherit;
  font-size: var(--t-footnote);
  font-weight: var(--w-strong);
  color: var(--brand-ink);
  cursor: pointer;
}
.pg-edit:active { opacity: 0.6; }

.pg-sec-lead {
  margin: 0 var(--gutter) var(--s-4);
  font-size: var(--t-footnote);
  line-height: var(--lh-body);
  color: var(--text-muted);
}

/* ── The month table ──────────────────────────────────────────
   Twelve rows of four columns will not fit a 320px phone. It scrolls
   inside its own box rather than taking the page sideways with it. */
.pg-table-wrap {
  margin: 0 var(--gutter) var(--s-4);
  overflow-x: auto;
  border-radius: var(--r-card);
  background: var(--app-card);
  box-shadow: var(--lift-1);
  -webkit-overflow-scrolling: touch;
}
.pg-table {
  width: 100%;
  min-width: 21rem;
  border-collapse: collapse;
  font-size: var(--t-footnote);
}
.pg-table caption {
  padding: var(--s-4) var(--s-4) var(--s-2);
  text-align: start;
  font-weight: var(--w-strong);
  color: var(--text);
}
.pg-table th, .pg-table td { padding: var(--s-3) var(--s-4); text-align: start; }
.pg-table thead th {
  font-size: var(--t-caption);
  font-weight: var(--w-medium);
  color: var(--text-muted);
  border-bottom: var(--hairline);
}
.pg-table tbody th { font-weight: var(--w-medium); color: var(--text); }
.pg-table tbody td { color: var(--text-muted); font-variant-numeric: tabular-nums; }
.pg-table tbody tr + tr th,
.pg-table tbody tr + tr td { border-top: var(--hairline); }

/* ═══════════════════════════════════════════════════════════════
   THE THREE STEPS
   ═══════════════════════════════════════════════════════════════ */

/* Progress in words above the bar. Three dots alone ask the reader
   to count them. */
.step-rail {
  padding: 0 var(--gutter) var(--s-4);
  border-bottom: var(--hairline);
}
.step-count {
  margin: 0 0 var(--s-3);
  font-size: var(--t-footnote);
  font-weight: var(--w-strong);
  color: var(--text-muted);
}
.step-bar { display: flex; gap: var(--s-2); }
.step-bar i {
  flex: 1;
  height: 6px;
  border-radius: 3px;
  background: var(--tile);
  transition: background-color var(--move) var(--out);
}
.step-bar i.on { background: var(--brand-ink); }

.step-panel[hidden] { display: none; }
/* The heading is focused on every step change so a screen reader lands on
   the new question. It is not interactive, so it must not draw a focus ring —
   a blue box around the title on every «تابع» reads as an error. */
.step-panel h3[tabindex="-1"]:focus { outline: none; }

/* The footer is fixed to the sheet, not the scroll — «تابع» must be
   reachable without scrolling to the end of twenty appliance chips. */
.step-foot {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: var(--s-3);
  padding: var(--s-4) var(--gutter) calc(var(--s-4) + env(safe-area-inset-bottom, 0px));
  border-top: var(--hairline);
  background: var(--app-card);
}
.step-foot .btn-x { width: 100%; }

/* A sheet that holds nineteen tools wants the whole screen. */
.sheet-card--tall { max-height: 94vh; }

/* ── Header buttons ───────────────────────────────────────────
/* Every round button is a full target, including the sheet's close. */
.rnd { width: 44px; height: 44px; min-width: 44px; }

/* ═══════════════════════════════════════════════════════════════
   بياناتي as a monitoring dashboard
   ═══════════════════════════════════════════════════════════════ */
.data-page { padding-block-start: var(--s-3); }
.dcard {
  margin: 0 var(--gutter) var(--s-4);
  padding: var(--s-4);
  background: var(--card);
  border-radius: 16px;
  box-shadow: var(--card-shadow);
}
.dcard-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-3);
  margin-block-end: var(--s-3);
}
.dcard-head h2 { margin: 0; font-size: var(--t-footnote); font-weight: var(--w-strong); }
.dcard-head .pg-edit, .dcard-head .link-btn { min-height: var(--hit-min); }
.rows, .chart-x, .est-gauge-card, .est-flow-card, .card-x, .state-x { background: var(--card); box-shadow: var(--card-shadow); border-radius: 16px; }
.chart-x { margin-block-end: var(--s-4); }
.pg-sec-head { padding-block: var(--s-6) var(--s-3); }
.pg-sec-head h2 { font-size: var(--t-headline); }

/* Plant header — name, size, edit */
.plant {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-3);
  margin: var(--s-2) var(--gutter) var(--s-4);
}
.plant h1 { margin: 0; font-size: var(--t-headline); line-height: var(--lh-tight); }
.plant-sub { margin: 2px 0 0; color: var(--text-muted); font-size: var(--t-caption); }
.plant .btn-x { min-width: 0; padding-inline: var(--s-4); }

/* ── Energy flow — the schematic ─────────────────────────────── */
.flow-card { padding-block: var(--s-3) var(--s-4); }
.flow-svg { display: block; width: 100%; height: auto; }
.flow-svg .wire { fill: none; stroke: var(--line); stroke-width: 2; }
.flow-svg .flow { fill: none; stroke: var(--amber-500); stroke-width: 2.5; stroke-linecap: round;
  stroke-dasharray: 4 10; opacity: 0; transition: opacity var(--move); }
.flow-svg .flow.is-on { opacity: 1; animation: flow-run 1.4s linear infinite; }
@keyframes flow-run { to { stroke-dashoffset: -28; } }
@media (prefers-reduced-motion: reduce) { .flow-svg .flow.is-on { animation: none; stroke-dasharray: none; opacity: 0.9; } }
.flow-svg .node { fill: var(--card); stroke: var(--line); stroke-width: 1.5; }
.flow-svg .node.is-hot { stroke: var(--amber-500); }
.flow-svg .glyph { fill: none; stroke: var(--brand-ink); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.flow-svg .inv { fill: var(--icon-well); stroke: var(--amber-500); stroke-width: 1.5; }
.flow-svg .glyph { stroke-width: 2; }
.flow-wrap { position: relative; max-width: 440px; margin-inline: auto; }
.flow-lab { position: absolute; display: flex; flex-direction: column; line-height: 1.15; pointer-events: none; }
.flow-lab b { font-size: var(--t-body); font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.flow-lab small { font-size: var(--t-caption); font-weight: 600; color: var(--text-muted); }
.flow-lab > span { font-size: var(--t-caption); color: var(--text-muted); margin-block-start: 2px; }
.fl-sun  { left: 2%; top: 2%;  width: 36%; align-items: stretch; text-align: right; }
.fl-inv  { left: 2%; top: 40%; width: 34%; align-items: stretch; text-align: right; }
.fl-batt, .fl-home, .fl-amp { top: 86%; width: 32%; transform: translateX(-50%); align-items: stretch; text-align: center; }
.fl-batt { left: 16.7%; } .fl-home { left: 50%; } .fl-amp { left: 83.3%; }
.flow-wrap { padding-block-end: 0; }
.flow-room { height: 78px; }
.fl-batt, .fl-home, .fl-amp { top: 88%; }
@media (max-width: 360px) { .flow-lab b { font-size: var(--t-footnote); } }
.flow-stamp { display: flex; align-items: center; gap: 6px; margin: var(--s-2) 0 0; font-size: var(--t-caption); color: var(--text-muted); }
.flow-stamp .icon { width: 16px; height: 16px; }

/* ── Weather strip — the sky, compact ────────────────────────── */
.wx { position: relative; overflow: hidden; padding: 0; min-height: 168px; }
.wx canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.wx-face {
  position: relative; z-index: 1; display: grid; grid-template-columns: 1fr auto; gap: var(--s-2) var(--s-4);
  padding: var(--s-4); min-height: 168px; align-content: end;
  color: #FFF8EC; text-shadow: 0 1px 2px rgba(0,0,0,0.5);
  background: linear-gradient(180deg, rgba(11,9,7,0) 20%, rgba(11,9,7,0.72) 100%);
}
.wx-top { position: absolute; z-index: 1; inset-block-start: var(--s-3); inset-inline: var(--s-3); display: flex; justify-content: space-between; }
.wx-chip { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 999px; background: rgba(11,9,7,0.62); color: #FFF8EC; font-size: var(--t-caption); font-weight: 600; }
.wx-temp { font-size: 40px; font-weight: 700; line-height: 1; }
.wx-temp small { font-size: 16px; font-weight: 600; margin-inline-start: 2px; }
.wx-word { font-size: var(--t-footnote); font-weight: 600; }
.wx-ends { display: flex; gap: var(--s-4); font-size: var(--t-caption); align-self: end; }
.wx-ends b { display: block; font-size: var(--t-footnote); }
.wx-ends i { font-style: normal; opacity: 0.85; }

/* ── KPI tiles ──────────────────────────────────────────────── */
.data-page .kpi-grid { margin: 0 var(--gutter) var(--s-4); }

/* ── Report — segmented, paged, one chart ────────────────────── */
.seg {
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 4px;
  padding: 4px; border-radius: 999px; background: var(--surface-alt);
}
.seg button {
  min-height: 44px; border: 0; border-radius: 999px; background: transparent;
  font: inherit; font-size: var(--t-caption); font-weight: 600; color: var(--text-muted); cursor: pointer;
}
.seg button[aria-pressed="true"] { background: var(--card); color: var(--brand-ink); box-shadow: 0 1px 4px rgba(80,50,10,0.15); }
.seg button:focus-visible { outline: 3px solid var(--focus); outline-offset: -3px; }
.pager { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); margin: var(--s-3) 0 var(--s-2); }
.pager button {
  width: 44px; height: 44px; border: 1px solid var(--line); border-radius: 50%; background: var(--card);
  display: inline-flex; align-items: center; justify-content: center; color: var(--text); cursor: pointer;
}
.pager button:disabled { opacity: 0.35; cursor: default; }
.pager-label { font-weight: 600; font-size: var(--t-footnote); text-align: center; }
.pager-label small { display: block; font-weight: 400; color: var(--text-muted); font-size: var(--t-caption); }
.rep-plot { height: 200px; }
.rep-plot canvas { width: 100%; height: 100%; display: block; }
.rep-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-2); margin-block-start: var(--s-3); padding-block-start: var(--s-3); border-top: 1px solid var(--line); }
.rep-stat b { display: block; font-size: var(--t-body); font-weight: 700; font-variant-numeric: tabular-nums; }
.rep-stat span { display: block; font-size: var(--t-caption); color: var(--text-muted); line-height: 1.3; }
.rep-stat i { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-inline-end: 4px; vertical-align: middle; }

/* ── Forecast — rings and the days ahead ─────────────────────── */
.rings { display: grid; grid-template-columns: auto auto 1fr; gap: var(--s-4); align-items: center; }
.ring { position: relative; width: 108px; height: 108px; }
.ring canvas { width: 100%; height: 100%; display: block; }
.ring-over { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.ring-over b { font-size: 22px; line-height: 1; font-variant-numeric: tabular-nums; }
.ring-over small { font-size: 16px; color: var(--text-muted); font-weight: 600; line-height: 1.1; }
.ring-l { text-align: center; font-size: var(--t-caption); color: var(--text-muted); margin-block-start: 4px; }
.fc-verdict b { display: block; font-size: var(--t-headline); line-height: 1.15; }
.fc-verdict span { font-size: var(--t-caption); color: var(--text-muted); }
.fc-days { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; margin-block-start: var(--s-4); }
.fc-day { display: flex; flex-direction: column; align-items: center; gap: 4px; min-width: 0; padding: var(--s-2) 2px; border-radius: 12px; }
.fc-day.is-today { background: var(--icon-well); }
.fc-day .d { font-size: var(--t-caption); font-weight: 600; color: var(--text-muted); white-space: nowrap; }
.fc-day.is-today .d { color: var(--brand-ink); }
.fc-day .icon { width: 22px; height: 22px; color: var(--brand-ink); }
.fc-day .w { color: var(--text-muted); }
.fc-bar { width: 100%; height: 72px; display: flex; align-items: flex-end; justify-content: center; }
.fc-bar i { display: block; width: min(22px, 70%); border-radius: 6px 6px 2px 2px; background: var(--chart-fill); min-height: 4px; }
.fc-day.is-today .fc-bar i { background: var(--brand-ink); }
.fc-day .k { font-size: var(--t-caption); font-weight: 700; font-variant-numeric: tabular-nums; }
.fc-day .c { font-size: var(--t-caption); color: var(--text-muted); white-space: nowrap; }
@media (max-width: 380px) { .rings { grid-template-columns: auto auto; } .fc-verdict { grid-column: 1 / -1; } .fc-day .c { display: none; } }
/* second pass: the weather card needs headroom, the tiles stack icon → label → value,
   the forecast strip scrolls rather than colliding */
.wx { min-height: 232px; }
.wx-face { min-height: 232px; padding-block-start: 72px; }
.data-page .kpi { min-height: 156px; display: grid; grid-template-rows: auto auto 1fr auto; gap: 6px; }
.data-page .kpi-l { flex-direction: column; align-items: flex-start; gap: 8px; }
.data-page .kpi-v { margin-block-start: 0; font-size: 28px; align-self: end; }
.data-page .kpi-d { white-space: normal; }
.rings { grid-template-columns: auto auto minmax(0, 1fr); }
.fc-verdict b { font-size: var(--t-body); }
@media (max-width: 440px) { .rings { grid-template-columns: auto auto; } .fc-verdict { grid-column: 1 / -1; } }
.fc-days { grid-template-columns: repeat(7, minmax(64px, 1fr)); gap: 6px; overflow-x: auto; scroll-snap-type: x proximity; padding-block-end: 4px; margin-inline: calc(var(--s-4) * -1); padding-inline: var(--s-4); }
.fc-day { scroll-snap-align: start; }
.fc-day .c { display: block; }

.plant .btn-x { width: auto; }
/* On a wide screen the dashboard keeps a phone-app measure, like the tab bar. */
@media (min-width: 900px) { .data-page { max-width: 780px; margin-inline: auto; } }

.faq details summary { min-height: var(--hit-min); display: flex; align-items: center; }

/* ═══ Review round 1 ═══ */
/* Every grouped list becomes stat tiles — the monitoring grammar, not an
   editorial page of rows. Interactive rows become tiles too. */
.rows { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-2); background: transparent; box-shadow: none; border-radius: 0; overflow: visible; }
.rows .rw { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; min-height: 124px; padding: var(--s-3); background: var(--card); border-radius: 14px; box-shadow: var(--card-shadow); border: 0; }
.rows .rw + .rw { border-top: 0; }
.rows .rw-ic { width: 34px; height: 34px; border-radius: 50%; background: var(--icon-well); color: var(--brand-ink); display: inline-flex; align-items: center; justify-content: center; }
.rows .rw-tx { order: 3; }
.rows .rw-tx b { font-size: var(--t-caption); font-weight: var(--w-medium); color: var(--text); line-height: 1.25; }
.rows .rw-tx span { font-size: var(--t-caption); color: var(--text-muted); line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.rows .rw-end { order: 2; margin-block-start: auto; justify-content: flex-start; text-align: start; white-space: normal; }
.rows .rw-val { font-size: var(--t-body); font-weight: 700; color: var(--text); line-height: 1.1; }
.rows .rw-go { display: none; }
.rows .rw--danger .rw-ic { background: var(--bad-bg); color: var(--bad); }
.rows .rw--static { grid-column: auto; }
@media (min-width: 640px) { .rows { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.pg-sec .rows + .chart-x, .pg-sec .rows + #card-uses, .pg-sec .rows + .pg-table-wrap { margin-block-start: var(--s-3); }
#pg-warn .card-x { margin-block-start: var(--s-3); }

/* Seven days fit the phone; the phase is a glyph, the cloud is a number. */
.fc-days { grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; overflow: visible; margin-inline: 0; padding-inline: 0; }
.fc-day .d { letter-spacing: -0.01em; }
.fc-day { padding-inline: 0; }
.fc-day .d, .fc-day .k, .fc-day .c { font-size: var(--t-caption); }
/* Only the smallest phones scroll the strip; the type never drops below the floor. */
@media (max-width: 360px) { .fc-days { grid-template-columns: repeat(7, minmax(54px, 1fr)); overflow-x: auto; scroll-snap-type: x proximity; } }
.fc-day .icon { width: 24px; height: 24px; }
.fc-day .icon[data-w="cloud"] { color: var(--text-muted); }

/* A chart card's title and its note stack on a phone instead of interleaving. */
.chart-x > header { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px var(--s-3); }
@media (max-width: 480px) { .chart-x > header > span { flex: 1 1 100%; font-size: var(--t-caption); } }

/* Four tiles stay 2×2 on a phone and go 4-up inside the desktop column. */
.data-page .kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 760px) { .data-page .kpi-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* The flow card yields the first screen sooner. */
.flow-wrap { max-width: 400px; }
.flow-room { height: 62px; }
.flow-card .chart-summary { margin-block-start: 0; }

/* ═══ Review round 2 ═══ */
.rows .rw-tx span { -webkit-line-clamp: 3; }
.data-page { padding-block-start: 0; }
.plant { margin-block-end: var(--s-3); }
.flow-card { padding-block-start: var(--s-2); }
.flow-room { height: 56px; }
.wx { min-height: 196px; }
.wx-face { min-height: 196px; padding-block-start: 60px; }
.data-page .stamp { margin-block-start: calc(var(--s-2) * -1); }

/* the seven columns borrow the card gutter so weekday names never touch */
.fc-days { margin-inline: calc(var(--s-4) * -1); padding-inline: 6px; }

/* ═══ Review round 2, mechanical leftovers ═══ */
/* An odd last tile spans the row instead of standing alone. */
.rows .rw--wide, .rows .rw:last-child:nth-child(odd) { grid-column: 1 / -1; }
.rows .rw--wide .rw-tx span, .rows .rw:last-child:nth-child(odd) .rw-tx span { -webkit-line-clamp: 4; }
@media (min-width: 640px) { .rows .rw:last-child:nth-child(odd) { grid-column: auto; } .rows .rw--wide { grid-column: 1 / -1; } }
.fc-days { gap: 5px; padding-inline: 4px; }
.fc-day .d { letter-spacing: -0.03em; }
