/* nodewatch layout. All colors, fonts, spacing and radii come from theme/ira.css.
 * Sized for a 16:9 4K TV read from 10-15 ft; still sane in a 1440p browser window. */

* { box-sizing: border-box; }
html, body { min-height: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-variant-numeric: tabular-nums;
  line-height: 1.25;
  display: flex;
  flex-direction: column;
  overflow: auto;                    /* a normal scrolling page; html.kiosk (end of file) is the one no-scroll layout */
  -webkit-font-smoothing: antialiased;
}
/* kiosk: no focus rings unless the keyboard is in use, no cursor after 3 s idle (app.js) */
:focus:not(:focus-visible) { outline: none; }
:focus-visible { outline: var(--hairline) solid var(--accent); outline-offset: var(--focus-offset); }
html.idle, html.idle * { cursor: none !important; }

/* ---- shared type roles ---- */
.label, .display {
  font-family: var(--font-display);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
}
.label { font-size: 0.72rem; color: var(--label-ink); margin: 0; }
.mono, .updated, .status-line, .chart-note, #foot, .banner-meta {
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
}

/* ---- header ---- */
#topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-4);
  padding: var(--page-y) var(--page-x) 0;
}
.brand { display: flex; align-items: center; gap: var(--space-3); min-width: 0; }
.seal {
  flex: none;
  height: var(--logo-h);
  width: calc(var(--logo-h) * 1.036);          /* seal is 1700 x 1641 */
  background-color: var(--logo-ink);
  -webkit-mask: url("/brand/ira-seal.svg") center / contain no-repeat;
  mask: url("/brand/ira-seal.svg") center / contain no-repeat;
}
.titles { min-width: 0; }
.display { font-size: 1.35rem; margin: 0; color: var(--accent); white-space: nowrap; }
.summary { font-size: 0.9rem; color: var(--ink-2); margin-top: 0.2rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.summary b { color: var(--ink); font-weight: 500; }
.summary .attn { color: var(--accent); font-weight: 500; }
.status { text-align: right; flex: none; }
.clock { font-size: 1.7rem; font-weight: 500; line-height: 1; }
.status-line { font-size: 0.66rem; color: var(--ink-3); margin-top: 0.35rem; display: inline-flex; align-items: center; gap: 0.45em; }
.status-line .dot { width: 0.5em; height: 0.5em; border-radius: 50%; background: var(--ink-3); }
.status-line.ok .dot { background: var(--accent); }
.status-line.warn, .status-line.bad { color: var(--ink-2); }
.status-line.warn .dot, .status-line.bad .dot { background: var(--accent); }
.page-link { display: inline-block; margin-top: 0.35rem; margin-left: var(--space-2); font-size: 0.81rem; color: var(--accent); text-decoration: none; }
.page-link:hover { text-decoration: underline; }
#view-3d::after { content: "\00a0\2192"; }

/* stale / login-failed strip: navy text stamped on the accent, no other alarm colors exist */
.banner {
  margin: var(--space-3) var(--page-x) 0;
  padding: 0.45rem 0.9rem;
  border-radius: var(--radius);
  background: var(--accent);
  color: var(--accent-ink);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
}

/* ---- main bands ---- */
main {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-3) var(--page-x) var(--space-3);
  min-height: 0;
}

/* Top band: the warehouse plan. NW | NE | Outside over SW | SE | (Outside spans both rows). */
.plan {
  flex: 0 0 auto;
  display: grid;
  grid-template-columns: 1fr 1fr minmax(12rem, 0.55fr);
  grid-template-rows: 1fr 1fr;
  gap: var(--space-3);
  min-height: 0;
}
.plan.flow {                                   /* nodes that do not follow the corner naming */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  grid-template-rows: none;
}
.card {
  background: var(--surface);
  border: var(--hairline) solid var(--line);
  border-top: var(--rule) solid var(--accent);
  border-radius: var(--radius);
  padding: var(--space-2) var(--space-4) var(--space-1);
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.card.pos-nw { grid-area: 1 / 1; }
.card.pos-ne { grid-area: 1 / 2; }
.card.pos-sw { grid-area: 2 / 1; }
.card.pos-se { grid-area: 2 / 2; }
.card.pos-outside { grid-area: 1 / 3 / 3 / 4; }
.corner-name { margin-bottom: var(--space-1); }
.rows { display: flex; flex-direction: column; flex: 1; }

/* one node reading: NAME | temp | humidity | delta + timestamp */
.node {
  display: grid;
  grid-template-columns: 3.4rem auto auto minmax(0, 1fr);
  align-items: baseline;
  column-gap: var(--space-4);
  padding: var(--space-1) 0 var(--space-2);
}
.corner .node + .node { border-top: var(--hairline) solid var(--line); }
.node-name { color: var(--label-ink); }
.reading { display: inline-flex; align-items: baseline; gap: 0.08em; white-space: nowrap; }
.reading .value { font-weight: 500; line-height: 1; }
.reading .unit { color: var(--ink-2); font-weight: 400; }
.reading.temp .value { font-size: 3rem; letter-spacing: -0.02em; }
.reading.temp .unit { font-size: 1.1rem; }
.reading.hum .value { font-size: 1.6rem; }
.reading.hum .unit { font-size: 0.9rem; }
.reading.out .value { color: var(--accent); }             /* out of range: the only highlight */
.node-meta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.25rem;
  text-align: right;
  justify-self: end;
  min-width: 4.5rem;
}
.delta { font-size: 0.9rem; color: var(--ink); display: inline-flex; align-items: baseline; gap: 0.25em; white-space: nowrap; }
.delta .arrow { font-size: 0.7em; color: var(--accent); }
.delta:empty, .delta.none { visibility: hidden; }
.updated { font-size: 0.66rem; color: var(--ink-2); white-space: nowrap; }
.flag {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.6rem;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  padding: 0.15em 0.55em;
  border-radius: var(--radius-sm);
  background: var(--accent);
  color: var(--accent-ink);
}
.flag:empty { display: none; }
.node.stale .reading, .node.stale .delta { opacity: var(--dim); }
.node.stale .updated { color: var(--ink-2); }

/* the Outside card (and any single-node card) stacks vertically */
.single { justify-content: center; }
.single .node { grid-template-columns: 1fr; row-gap: var(--space-3); padding: 0; align-content: center; }
.single .node-name { color: var(--label-ink); }
.single .reading.temp .value { font-size: 3.8rem; }
.single .node-meta { align-items: flex-start; text-align: left; justify-self: start; }

.empty {
  grid-column: 1 / -1;
  background: var(--surface);
  border: var(--hairline) solid var(--line);
  border-radius: var(--radius);
  padding: var(--space-4);
  color: var(--ink-2);
  font-size: 0.9rem;
  line-height: 1.5;
}
.empty b { color: var(--ink); font-weight: 500; }
.empty code { font-family: var(--font-mono); color: var(--ink); }

/* ---- bottom band: history ---- */
/* Never `flex: 1 1 0` here. Below 1101px `main` is content-sized (flex: none) and Chrome sizes a
 * column flex container from each item's flex-basis clamped by its min-height, so a definite 0px
 * basis together with `min-height: 0` made this section contribute zero height: it hung outside
 * `main` and the footer, laid out after `main`, was painted over the chart legend. `auto` (or a
 * 0% basis, which resolves to content against an indefinite container) sizes from the content. */
.charts { flex: none; display: flex; flex-direction: column; gap: var(--space-2); }
.chart-toolbar { display: flex; justify-content: space-between; align-items: center; gap: var(--space-4); }
.legend { display: flex; flex: 1 1 auto; flex-wrap: wrap; gap: 0.3rem var(--space-3); min-width: 0; }
.legend-item { display: inline-flex; align-items: center; gap: 0.45em; font-size: 0.7rem; color: var(--ink-2); text-transform: uppercase; letter-spacing: var(--tracking-caps); font-family: var(--font-display); font-weight: 600; }
.legend-item .swatch { width: 1.1em; height: 0.18em; border-radius: var(--hairline); background: var(--swatch); /* --swatch is set per item by app.js to the series token */ }
.chart-controls { display: flex; flex: none; align-items: center; gap: var(--space-3); }
.chart-note { font-size: 0.66rem; color: var(--ink-2); }
.range-buttons { display: flex; gap: var(--space-1); }
.range-buttons button {
  font: inherit;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--ink-2);
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  padding: 0.3em 0.8em;
  cursor: pointer;
  min-width: 3em;
}
.range-buttons button:hover { color: var(--ink); }
.range-buttons button.active { background: var(--accent); color: var(--accent-ink); }
.chart-row { flex: none; display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
.chart-box {
  background: var(--surface);
  border: var(--hairline) solid var(--line);
  border-radius: var(--radius);
  padding: var(--space-3) var(--space-3) var(--space-2);
  display: flex;
  flex-direction: column;
  min-height: 16rem;
}
.chart-box .label { margin-bottom: var(--space-2); }
.canvas-wrap { position: relative; flex: 1; min-height: 4rem; }
.canvas-wrap canvas { position: absolute; inset: 0; }

/* ---- footer ---- */
#foot {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  padding: 0 var(--page-x) var(--page-y);
  font-size: 0.66rem;
  color: var(--accent);
  letter-spacing: var(--tracking-caps-wide);
}

/* ---- narrow screens: a phone or a half-width window, scrolling allowed ---- */
@media (max-width: 900px) {
  #topbar { flex-direction: column; align-items: flex-start; }
  .status { text-align: left; }
  .plan { grid-template-columns: 1fr; grid-template-rows: none; }
  .card.pos-nw, .card.pos-ne, .card.pos-sw, .card.pos-se, .card.pos-outside { grid-area: auto; }
  .chart-row { grid-template-columns: 1fr; }
  .chart-box { min-height: 14rem; }
  .chart-toolbar { flex-wrap: wrap; }
  #foot { flex-direction: column; gap: var(--space-1); }
}
@media (max-width: 480px) {
  .node { grid-template-columns: 3rem 1fr; }
  .node-meta { grid-column: 1 / -1; flex-direction: row; justify-content: space-between; align-items: baseline; }
}

/* Refined operations interface. Semantic theme tokens remain the styling contract. */
.label, .display { font-family: var(--font-body); text-transform: none; letter-spacing: normal; }
#topbar { padding-bottom: var(--space-3); border-bottom: var(--hairline) solid var(--line); }
.brand { gap: var(--space-3); }
.eyebrow { font-size: 0.81rem; font-weight: 600; letter-spacing: var(--tracking-caps-wide); color: var(--accent); margin-bottom: var(--space-1); }
.eyebrow span { color: var(--ink-3); padding: 0 var(--space-2); }
.display { font-size: 2.15rem; font-weight: 500; color: var(--ink); white-space: normal; letter-spacing: -0.03em; }
.summary { font-size: 0.97rem; color: var(--ink-2); margin-top: var(--space-1); }
.clock { font-size: 1.14rem; font-weight: 400; }
.status-line { font-family: var(--font-body); text-transform: none; letter-spacing: normal; font-size: 0.94rem; }
.status-line.ok .dot { background: var(--positive); }
main { gap: var(--space-2); }
.overview { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border: var(--hairline) solid var(--line); border-radius: var(--radius); background: var(--surface); margin-bottom: var(--space-2); }
.metric { padding: var(--space-3) var(--space-4); display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.metric + .metric { border-left: var(--hairline) solid var(--line); }
.metric.outside-metric { display: none; }          /* the kiosk band shows it; the page has the Outside card */
.metric.outside-metric strong { color: var(--accent); }
.metric-label { font-size: 0.92rem; color: var(--ink-2); }
.metric strong { font-size: var(--metric-size); font-weight: 500; letter-spacing: -0.04em; line-height: 1.2; }
.metric-detail { font-size: 0.81rem; color: var(--ink-2); }
.metric .health-value { font-size: 1.86rem; color: var(--positive); padding: 0.36rem 0; letter-spacing: -0.02em; }
.metric .health-value.attention { color: var(--accent); }
.section-heading { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-2); padding: var(--space-1) 0; }
.section-heading h2 { font-size: 1.02rem; font-weight: 500; margin: 0; }
.section-heading > span { font-size: 0.81rem; color: var(--ink-3); }
.heading-divider { margin: 0 var(--space-2); }
.plan { gap: var(--space-2); grid-template-columns: 1fr 1fr minmax(10rem, 0.4fr); }
.card { border-top: var(--hairline) solid var(--line); padding: var(--space-2) var(--panel-padding); }
.corner-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-2); }
.corner-name { font-size: 1.02rem; font-weight: 500; color: var(--ink); margin: 0; }
.zone-code { font-family: var(--font-mono); font-size: 0.81rem; color: var(--ink-3); border: var(--hairline) solid var(--line); padding: 0.2em 0.45em; border-radius: var(--radius-sm); }
.column-labels, .node { display: grid; grid-template-columns: var(--card-columns); column-gap: var(--space-2); }
.column-labels { font-size: 0.68rem; color: var(--ink-3); padding-bottom: var(--space-1); }
.column-labels span:last-child { text-align: right; }
.node { padding: var(--space-2) 0; align-items: center; }
.node-name { font-size: 0.88rem; font-weight: 400; }
.reading.temp .value { font-size: 2.63rem; font-weight: 500; letter-spacing: -0.05em; }
.reading.temp .unit { font-size: 0.96rem; color: var(--ink-3); }
.reading.hum .value { font-size: 1.56rem; font-weight: 400; }
.reading.hum .unit { font-size: 0.94rem; color: var(--ink-3); }
.node-meta { min-width: 0; gap: var(--space-1); }
.delta { font-size: 0.84rem; color: var(--ink-2); }
.updated { font-family: var(--font-body); letter-spacing: normal; font-size: 0.74rem; text-transform: none; color: var(--ink-3); }
.flag { font-family: var(--font-body); font-size: 0.68rem; }
.single { background: var(--surface-2); }
.single .node { row-gap: var(--space-2); }
.single .node-name { font-size: 1.02rem; color: var(--ink); font-weight: 500; }
.single .node-name::after { content: 'EXTERIOR REFERENCE'; display: block; font-size: 0.61rem; font-weight: 400; color: var(--ink-3); letter-spacing: var(--tracking-caps); margin-top: var(--space-1); }
.single:not(.pos-outside) .node-name::after { content: none; }
.single .reading.temp .value { font-size: 3.81rem; }
.single .node-meta { margin-top: var(--space-2); }
.charts { gap: var(--space-2); }
.chart-toolbar { gap: var(--space-2); }
.legend { gap: var(--space-1) var(--space-3); }
.legend-item { font-family: var(--font-body); font-size: 0.74rem; font-weight: 400; text-transform: none; letter-spacing: normal; }
.chart-note { font-family: var(--font-body); font-size: 0.74rem; text-transform: none; letter-spacing: normal; }
.range-buttons { padding: var(--space-1); background: var(--surface); border: var(--hairline) solid var(--line); border-radius: var(--radius-sm); gap: 0; }
.range-buttons button { font-family: var(--font-body); font-size: 0.81rem; text-transform: none; letter-spacing: normal; font-weight: 500; padding: 0.35em 0.8em; }
.range-buttons button:hover { background: var(--surface-2); }
.range-buttons button.active { background: var(--accent); color: var(--accent-ink); }
.chart-row { gap: var(--space-2); }
.chart-box { padding: var(--space-3) var(--panel-padding) var(--space-2); }
.chart-box .label { font-size: 1.05rem; color: var(--ink); font-weight: 500; }
#foot { color: var(--ink-3); font-family: var(--font-body); text-transform: none; letter-spacing: normal; font-size: 0.74rem; }
@media (max-width: 1100px) {
  .plan { grid-template-columns: 1fr 1fr; }
  .card.pos-outside { grid-area: 3 / 1 / 4 / 3; }
  .single .node { grid-template-columns: repeat(4, 1fr); align-items: center; }
  .single .node-meta { margin: 0; justify-self: end; }
  .single .reading.temp .value { font-size: 2.63rem; }
  .chart-box { min-height: 15rem; }
  .chart-toolbar { flex-wrap: wrap; }
  .chart-controls { margin-left: auto; }
  .metric { padding: var(--space-3); }
}
@media (max-width: 900px) {
  #topbar { flex-direction: row; align-items: center; }
  .status { text-align: right; }
  .clock { font-size: 0.94rem; }
  .overview { grid-template-columns: 1fr 1fr; }
  .metric:nth-child(3) { border-left: 0; }
  .metric:nth-child(n+3) { border-top: var(--hairline) solid var(--line); }
  .plan { grid-template-columns: 1fr; }
  .card.pos-nw, .card.pos-ne, .card.pos-sw, .card.pos-se, .card.pos-outside { grid-area: auto; }
  .section-heading > span { display: none; }
}
@media (max-width: 640px) {
  /* The seal plus the fixed-width clock/status column no longer leave room for the titles beside
   * them, so the status row drops under the brand (it already did at <=480px). */
  #topbar { flex-wrap: wrap; }
  .status { display: flex; justify-content: space-between; align-items: center; width: 100%; }
  .status-line { margin: 0; }
  .summary { white-space: normal; }
}
@media (max-width: 480px) {
  .seal { --logo-h: 5.6rem; }
  .display { font-size: 1.50rem; }
  .summary { font-size: 0.88rem; }
  .column-labels, .node { grid-template-columns: 2.5rem 1.2fr 0.8fr 1fr; }
  .node-meta { grid-column: auto; flex-direction: column; align-items: flex-end; }
  .reading.temp .value { font-size: 2.24rem; }
  .single .node { grid-template-columns: 1fr 1fr; }
  .single .node-meta { justify-self: start; align-items: flex-start; }
  .chart-controls { width: 100%; justify-content: space-between; }
}
/* Desktops: a scrolling page like everything else; only the kiosk fills the screen. */
@media (min-width: 1101px) {
  .metric { padding-top: 0.6rem; padding-bottom: 0.6rem; }
  .corner-header { margin-bottom: var(--space-1); }
  .node { padding-top: var(--space-1); padding-bottom: var(--space-1); }
}
/* 1080-class desktops (a 1920x1080 or 2560x1440 monitor, 16:9, under ~1150 CSS px tall): a denser header,
 * readings band and cards so the 3D models start on the first screen instead of just below it. */
@media (min-width: 1500px) and (max-height: 1150px) and (min-aspect-ratio: 3/2) {
  :root { --logo-h: 5.2rem; --metric-size: 2.1rem; }
  #topbar { padding-top: var(--space-2); padding-bottom: var(--space-2); }
  .display { font-size: 1.8rem; }
  .eyebrow { margin-bottom: 0; }
  .summary { margin-top: 0; }
  main { gap: var(--space-1); padding-top: var(--space-2); }
  .overview { margin-bottom: 0; }
  .metric { padding-top: 0.35rem; padding-bottom: 0.35rem; gap: 0; }
  .metric .health-value { font-size: 1.5rem; padding: 0.15rem 0; }
  .section-heading { padding: 0.15rem 0; }
  .card { padding-top: var(--space-1); padding-bottom: var(--space-1); }
  .corner-header { margin-bottom: 0; }
  .column-labels { padding-bottom: 0; }
  .node { padding-top: 0.15rem; padding-bottom: 0.15rem; }
  .reading.temp .value { font-size: 2.2rem; }
  .reading.hum .value { font-size: 1.35rem; }
  .single .reading.temp .value { font-size: 3rem; }
  .v3d { gap: var(--space-1); }
  .stage { aspect-ratio: 16 / 9; }
}


/* ==== Rackhouse in 3D (section #3d; static/field3d.js) ==================================== */
.v3d { flex: none; display: flex; flex-direction: column; gap: var(--space-2); scroll-margin-top: var(--space-3); }
.v3d-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); }
.v3d-toolbar .est-note { flex: 1 1 14rem; }
.est-note { font-size: 0.81rem; color: var(--ink-2); }
.seg { display: flex; gap: 0; padding: var(--space-1); background: var(--surface); border: var(--hairline) solid var(--line); border-radius: var(--radius-sm); }
.seg button, .play, .latest {
  font: inherit; font-family: var(--font-body); font-size: 0.81rem; font-weight: 500; color: var(--ink-2);
  background: transparent; border: 0; border-radius: var(--radius-sm); padding: 0.35em 0.8em; cursor: pointer; min-width: 3em;
}
.seg button:hover, .latest:hover { background: var(--surface-2); color: var(--ink); }
.seg button.active { background: var(--accent); color: var(--accent-ink); }
.check { display: inline-flex; align-items: center; gap: 0.4em; font-size: 0.81rem; color: var(--ink-2); cursor: pointer; }
.check input { accent-color: var(--accent); }
/* The way to the airflow page (/airflow): a hero panel right under the Rackhouse temperature and humidity at the top. A still of that page drifts slowly behind a
 * large title and a button in the accent; the whole panel is the link. Its colours are its own (the still is a night
 * scene) whatever the page's theme. Not on the kiosk (no pointer, no room) and not in the embed (the Squarespace page
 * stays as it is). */
.flow-cta { position: relative; display: flex; flex: none; align-items: flex-end; min-height: clamp(13rem, min(25vw, 40vh), 21rem); margin: var(--space-2) 0; padding: var(--space-4) calc(var(--panel-padding) * 1.4);
  overflow: hidden; border: var(--hairline) solid var(--line); border-top: var(--rule) solid var(--accent); border-radius: var(--radius); background: var(--ira-navy); color: var(--ira-cream);
  text-decoration: none; isolation: isolate; box-shadow: 0 0.6rem 2rem rgb(0 0 0 / 0.28); transition: box-shadow 0.3s, transform 0.3s; }
.flow-cta-still { position: absolute; inset: -10% -5%; z-index: -1; background: url("/brand/airflow-still.jpg") 58% 48% / cover no-repeat; animation: flow-cta-drift 38s ease-in-out infinite alternate; transition: filter 0.4s; }
.flow-cta::after { content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(to right, rgb(6 10 16 / 0.88), rgb(6 10 16 / 0.45) 42%, rgb(6 10 16 / 0) 72%), linear-gradient(to top, rgb(6 10 16 / 0.55), rgb(6 10 16 / 0) 45%); }
@keyframes flow-cta-drift { from { transform: scale(1.02) translate3d(-2%, 1%, 0); } to { transform: scale(1.12) translate3d(2.5%, -1.5%, 0); } }
.flow-cta-text { display: flex; flex-direction: column; align-items: flex-start; gap: 0.45rem; max-width: 36rem; }
.flow-cta-kicker { font-family: var(--font-mono); font-size: 0.78rem; font-weight: 500; letter-spacing: var(--tracking-caps-wide); text-transform: uppercase; color: var(--ira-mustard); }
.flow-cta-title { font-family: var(--font-display); font-size: clamp(2.3rem, 3.4vw, 3.2rem); font-weight: 500; line-height: 1.05; letter-spacing: -0.01em; }
.flow-cta-sub { font-size: 0.95rem; line-height: 1.4; color: color-mix(in oklab, var(--ira-cream) 80%, transparent); max-width: 30rem; }
.flow-cta-button { display: inline-flex; align-items: center; gap: 0.6rem; margin-top: 0.5rem; min-height: 3.1rem; box-sizing: border-box; padding: 0.75rem 1.4rem; border-radius: 2rem; background: var(--ira-mustard); color: var(--ira-navy);
  font-family: var(--font-mono); font-size: 0.8rem; font-weight: 500; letter-spacing: var(--tracking-caps); text-transform: uppercase; transition: background-color 0.2s, gap 0.25s; }
.flow-cta-play { width: 0; height: 0; border-left: 0.6rem solid currentColor; border-top: 0.38rem solid transparent; border-bottom: 0.38rem solid transparent; }
.flow-cta:hover, .flow-cta:focus-visible { box-shadow: 0 0.9rem 2.6rem rgb(0 0 0 / 0.4); transform: translateY(-0.12rem); }
.flow-cta:hover .flow-cta-still, .flow-cta:focus-visible .flow-cta-still { filter: brightness(1.18); }
.flow-cta:hover .flow-cta-button, .flow-cta:focus-visible .flow-cta-button { background: var(--ira-yellow); gap: 0.85rem; }
.flow-cta:focus-visible { outline: var(--rule) solid var(--accent); outline-offset: var(--focus-offset); }
html.kiosk .flow-cta, html[data-view="embed"] .flow-cta { display: none; }
/* the backdrop in three sizes, so it is neither a megabyte on a phone nor a blur on a 6K panel: the 16:9 still for
   narrow screens (the panel is nearly square-ish there), a 4:1 hero for desktops, its 6000 px original for big or dense ones */
@media (min-width: 900px) { .flow-cta-still { inset: -12% -24% -12% -4%; background-image: url("/brand/airflow-hero-2400.jpg"); background-position: 50% 50%; } }      /* wider than the panel: the building runs off its right edge */
@media (min-width: 2200px), (min-width: 900px) and (min-resolution: 1.5dppx) { .flow-cta-still { background-image: url("/brand/airflow-hero-6000.jpg"); } }
@media (max-width: 640px) { .flow-cta { min-height: 15rem; padding: var(--space-3) var(--panel-padding); } .flow-cta-sub { font-size: 0.85rem; } .flow-cta::after { background: linear-gradient(to top, rgb(6 10 16 / 0.9), rgb(6 10 16 / 0.35) 60%, rgb(6 10 16 / 0.1)); } }
@media (prefers-reduced-motion: reduce) { .flow-cta-still { animation: none; } .flow-cta, .flow-cta-button { transition: none; } .flow-cta:hover { transform: none; } }
.v3d-unavailable { display: none; padding: var(--space-3) var(--panel-padding); background: var(--surface); border: var(--hairline) solid var(--line); border-radius: var(--radius); color: var(--ink-2); font-size: 0.9rem; }
.v3d.unavailable .v3d-unavailable { display: block; }
.v3d.unavailable .models, .v3d.unavailable .timebar, .v3d.unavailable .v3d-toolbar { display: none; }

.models { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); container-type: inline-size; }
.model {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(10rem, 12rem);
  /* the last row takes whatever the stats column has over the stage and its legend, so the legend stays right under
     the stage instead of being pushed down a stretched row */
  grid-template-rows: auto auto auto 1fr;
  grid-template-areas: "head head" "stage stats" "legend stats" ". stats";
  gap: var(--space-2);
  background: var(--surface);
  border: var(--hairline) solid var(--line);
  border-radius: var(--radius);
  padding: var(--space-3) var(--panel-padding) var(--space-3);
  min-width: 0;
}
.model-head { grid-area: head; display: flex; justify-content: space-between; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.model-head .label { font-size: 1.05rem; color: var(--ink); font-weight: 500; }
.model-head .unit { color: var(--ink-3); font-weight: 400; font-size: 0.85em; }
.model-note { font-size: 0.74rem; color: var(--ink-3); }

.stage { grid-area: stage; position: relative; aspect-ratio: 3 / 2; min-height: 14rem; min-width: 0; max-width: 100%; border-radius: var(--radius-sm); background: var(--bg); overflow: hidden; border: var(--hairline) solid var(--line); }
/* A one-finger vertical swipe over a model scrolls the page (touch-action: pan-y) until the model is
 * activated by a tap; then the canvas takes every gesture (drag turns, pinch and wheel zoom). */
.stage canvas.gl { position: absolute; inset: 0; top: var(--warn-h, 0px); width: 100%; height: calc(100% - var(--warn-h, 0px)); display: block; touch-action: pan-y; cursor: grab; }
.stage.armed canvas.gl { touch-action: none; }
.stage canvas.gl:active { cursor: grabbing; }
.rotate-hint { display: inline-flex; align-items: center; gap: 0.5em; margin-left: auto; font-size: max(0.7rem, 11px); color: var(--ink-2); background: var(--surface-2); border: var(--hairline) solid var(--line); padding: 0.15em 0.6em; border-radius: var(--radius-sm); white-space: nowrap; }
.rotate-hint .release { font: inherit; font-weight: 500; color: var(--accent-ink); background: var(--accent); border: 0; border-radius: var(--radius-sm); padding: 0.1em 0.6em; cursor: pointer; }
.model:has(.stage.armed) .rotate-hint { color: var(--ink); border-color: var(--accent); }
html.kiosk .rotate-hint { display: none; }

.labels { position: absolute; inset: 0; top: var(--warn-h, 0px); pointer-events: none; overflow: hidden; }
.slabel {
  position: absolute; transform: translate(-50%, -100%); white-space: nowrap;
  font-family: var(--font-mono); font-size: max(0.66rem, 10.5px); letter-spacing: 0.02em; line-height: 1.15;
  color: var(--ink); text-align: center; padding: 0.1em 0.35em; border-radius: var(--radius-sm);
  background: color-mix(in oklab, var(--bg) 72%, transparent);
}
.slabel.below { transform: translate(-50%, 0); }
.slabel .v { font-weight: 500; }
.slabel.missing, .slabel.held { color: var(--ink-2); }
.slabel.missing .v { color: var(--accent); }
.slabel.compass { font-family: var(--font-display); font-weight: 600; font-size: 0.72rem; color: var(--ink-3); background: transparent; transform: translate(-50%, -50%); letter-spacing: var(--tracking-caps); }
.slabel.tier { font-family: var(--font-mono); font-weight: 400; font-size: max(0.6rem, 10px); letter-spacing: 0; }
.stat.tiers .stat-value { font-family: var(--font-mono); font-size: 0.8rem; letter-spacing: 0; white-space: normal; line-height: 1.4; }
.stage-note { position: absolute; left: var(--space-2); right: var(--space-2); bottom: var(--space-2); font-size: max(0.66rem, 10.5px); color: var(--ink-3); display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0.2em 1em; align-items: center; pointer-events: none; }
.height-note { font-family: var(--font-mono); letter-spacing: 0.02em; }
.measured-key, .estimated-key { display: inline-block; width: 0.7em; height: 0.7em; border-radius: 50%; margin-right: 0.35em; vertical-align: -0.05em; box-sizing: border-box; }
.measured-key { background: var(--ink); border: 2px solid var(--ink); }
.estimated-key { background: color-mix(in oklab, var(--ink) 30%, transparent); border: 1px dashed var(--ink-3); }
.field-warn {
  position: absolute; left: var(--space-2); top: var(--space-2); max-width: calc(100% - 2 * var(--space-2));
  padding: 0.3em 0.7em; border-radius: var(--radius-sm); background: var(--accent); color: var(--accent-ink);
  font-size: 0.74rem; font-weight: 500; pointer-events: none;
}
.popover {
  position: absolute; z-index: 2; min-width: 10rem; max-width: 80%; padding: var(--space-2) var(--space-3);
  background: var(--surface-2); border: var(--hairline) solid var(--line); border-radius: var(--radius-sm);
  color: var(--ink); font-size: 0.81rem; line-height: 1.4; box-shadow: 0 0.4rem 1.2rem color-mix(in oklab, var(--bg) 60%, transparent);
}
.popover b { font-weight: 500; }
.popover .big { font-size: 1.5rem; font-weight: 500; letter-spacing: -0.03em; display: block; }
.popover .meta { color: var(--ink-2); font-size: 0.74rem; }
.popover button { position: absolute; top: 0.2em; right: 0.2em; font: inherit; background: transparent; border: 0; color: var(--ink-2); cursor: pointer; padding: 0.2em 0.5em; }
.fallback { position: absolute; inset: 0; top: var(--warn-h, 0px); }
.fallback canvas { width: 100%; height: 100%; display: block; touch-action: pan-y; }
.stage.armed .fallback canvas { touch-action: none; }
.model.flat .stage { aspect-ratio: 1 / 1; }

.legend-bar { grid-area: legend; display: flex; flex-direction: column; gap: 0.25rem; padding-top: var(--space-1); }
.legend-title { font-size: 0.74rem; color: var(--ink-2); display: flex; gap: 0.5em; }
.legend-unit { color: var(--ink-3); }
.legend-mode { margin-left: auto; color: var(--ink-3); }
.legend-scale { position: relative; height: 0.9rem; margin-top: 1.1rem; }
.legend-gradient { position: absolute; inset: 0; border-radius: var(--radius-sm); border: var(--hairline) solid var(--line); }
.legend-outside { position: absolute; top: -1.15rem; bottom: 0; left: 0; width: 0; pointer-events: none; }
.legend-outside .tick { position: absolute; bottom: -0.15rem; left: 50%; width: 0; height: 0; transform: translateX(-50%); border-left: 0.32rem solid transparent; border-right: 0.32rem solid transparent; border-top: 0.42rem solid var(--ink); }
.legend-outside .tag { position: absolute; top: 0; left: 0; transform: translateX(-50%); white-space: nowrap; font-size: max(0.7rem, 11px); color: var(--ink); font-weight: 500; }
.legend-outside.pin-lo .tag { transform: none; }
.legend-outside.pin-hi .tag { transform: translateX(-100%); }
.legend-outside[hidden] { display: none; }
.legend-ticks { display: flex; justify-content: space-between; font-family: var(--font-mono); font-size: max(0.72rem, 11px); color: var(--ink-2); }

.stats { grid-area: stats; display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; font-size: 0.81rem; }
.stat { display: flex; flex-direction: column; padding: 0.3rem 0; border-bottom: var(--hairline) solid var(--line); }
.stat:last-child { border-bottom: 0; }
.stat-label { color: var(--ink-2); font-size: 0.74rem; }
.stat-value { font-size: 1.35rem; font-weight: 500; letter-spacing: -0.03em; line-height: 1.15; }
.stat-value.small { font-size: 0.95rem; letter-spacing: -0.01em; }
.stat-detail { color: var(--ink-3); font-size: 0.7rem; }
.stat.outside .stat-value { color: var(--accent); }
.stat.hero .stat-value { font-size: 1.7rem; }

.timebar { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-1) 0; }
.play, .latest { flex: none; background: var(--surface); border: var(--hairline) solid var(--line); }
.play { width: 2.6em; font-size: 0.95rem; }
.play[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); }
#scrub { flex: 1 1 auto; min-width: 0; accent-color: var(--accent); height: 1.2rem; }
.timestamp { flex: none; display: flex; flex-direction: column; align-items: flex-end; min-width: 11rem; }
#frame-time { font-size: 0.95rem; font-weight: 500; }

@media (max-width: 1100px) {
  .models { grid-template-columns: 1fr; }
  .stage { aspect-ratio: 16 / 10; }
}
@media (max-width: 640px) {
  .model { grid-template-columns: 1fr; grid-template-rows: auto auto auto auto; grid-template-areas: "head" "stage" "legend" "stats"; padding: var(--space-2); }
  .stage { aspect-ratio: 5 / 4; }
  .stats { display: grid; grid-template-columns: 1fr 1fr; gap: 0 var(--space-2); }
  .stat.hero { grid-column: 1 / -1; }
  .timebar { flex-wrap: wrap; }
  .timestamp { align-items: flex-start; order: 3; width: 100%; min-width: 0; }
  .model-note { display: none; }
}

/* Very wide desktop windows (a 5K panel at 2x is 2560 CSS px, fractional scaling 3200): the page keeps
 * using the width; models and charts grow with it, the stage stays 3:2, the charts get taller. */
@media (min-width: 2200px) {
  :root { --page-x: 2vw; }
  .chart-box { min-height: 20rem; }
  .model { grid-template-columns: minmax(0, 1fr) minmax(12rem, 16rem); }
}

/* Two cards side by side, each with its stats beside the stage, need room: the stage is at least 14rem tall at 3:2,
 * so 21rem wide, plus the stats column (12rem; 16rem on very wide windows), the gaps and the padding. When the pair of
 * cards is narrower than that (windows just over 1100 px, and again from about 2200 to 2900 px where the headline column
 * takes a quarter of the width: a 5K monitor at 2x), the stats go under the stage, which then gets the whole card.
 * Before this the stage simply ran over the stats. */
@media (min-width: 1101px) { @container (max-width: 76rem) {
  .model { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto; grid-template-areas: "head" "stage" "legend" "stats"; }
  .stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: 0 var(--space-3); align-items: start; }
} }
@media (min-width: 2200px) { @container (max-width: 86rem) {
  .model { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto; grid-template-areas: "head" "stage" "legend" "stats"; }
  .stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: 0 var(--space-3); align-items: start; }
} }

/* ==== Estimated airflow: the layer on the models, the headline strip, the analysis panel ============= */
/* The layer's overlay sits between the GL canvas and the DOM labels: 2D, drawn at the device ratio. */
.stage canvas.flow { position: absolute; inset: 0; top: var(--warn-h, 0px); width: 100%; height: calc(100% - var(--warn-h, 0px)); display: block; pointer-events: none; }
.v3d.airflow-off canvas.flow { display: none; }
.est-tag { display: inline-block; font-family: var(--font-body); font-size: 0.66rem; font-weight: 500; letter-spacing: var(--tracking-caps); text-transform: uppercase; color: var(--accent); border: var(--hairline) solid var(--accent); border-radius: var(--radius-sm); padding: 0.1em 0.5em; vertical-align: 0.1em; white-space: nowrap; }
.airflow-check .est-tag { margin-left: 0.4em; }
.arrow-key { display: inline-block; width: 1.1em; height: 0; border-top: 0.18em solid var(--accent); margin-right: 0.35em; vertical-align: 0.2em; position: relative; }
.arrow-key::after { content: ""; position: absolute; right: -0.1em; top: -0.32em; border: 0.24em solid transparent; border-left: 0.36em solid var(--accent); }
.arrow-key.env { border-top-color: var(--series-outside); }
.arrow-key.env::after { border-left-color: var(--series-outside); }
.mode-seg { padding: 0.15rem; }
.mode-seg button { font-size: 0.74rem; padding: 0.25em 0.6em; min-width: 0; }
.grade { display: inline-block; font-family: var(--font-body); font-size: 0.62rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; padding: 0.05em 0.45em; border-radius: var(--radius-sm); border: var(--hairline) solid var(--line); color: var(--ink-2); vertical-align: 0.15em; }
.grade.g2 { color: var(--accent-ink); background: var(--accent); border-color: var(--accent); }
.grade.g1 { color: var(--accent); border-color: var(--accent); }
.grade.g0 { color: var(--ink-3); border-style: dashed; }
.popover .grade { margin-left: 0.4em; }
.popover .big small { font-size: 0.5em; color: var(--ink-2); font-weight: 400; }
.popover .meta i { color: var(--accent); font-style: normal; }

/* headline numbers beside the models: a row under the models; a column beside them on wide screens */
.v3d-body { display: flex; flex-direction: column; gap: var(--space-2); }
.airflow-headline { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 0 var(--space-3); background: var(--surface); border: var(--hairline) solid var(--line); border-radius: var(--radius); padding: var(--space-2) var(--panel-padding); }
.airflow-headline.empty { display: block; }
.ah-empty { color: var(--ink-3); font-size: 0.81rem; }
.ah-tile { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; padding: var(--space-1) 0; }
.ah-tile + .ah-tile { border-left: var(--hairline) solid var(--line); padding-left: var(--space-3); }
.ah-label { font-size: 0.74rem; color: var(--ink-2); display: flex; align-items: center; gap: 0.4em; flex-wrap: wrap; }
.ah-value { font-size: 1.5rem; font-weight: 500; letter-spacing: -0.03em; line-height: 1.15; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ah-value small { font-size: 0.55em; color: var(--ink-2); font-weight: 400; letter-spacing: 0; }
.ah-value .regime { font-size: 0.95rem; font-weight: 500; letter-spacing: -0.01em; white-space: normal; line-height: 1.25; }
.ah-range { font-size: 0.74rem; color: var(--ink-2); }
.ah-sub { font-size: 0.7rem; color: var(--ink-3); }
.ah-tag { grid-column: 1 / -1; display: flex; gap: var(--space-2); align-items: center; flex-wrap: wrap; border-top: var(--hairline) solid var(--line); margin-top: var(--space-1); padding-top: var(--space-1); }
.ah-est { font-family: var(--font-body); font-size: 0.66rem; font-weight: 500; letter-spacing: var(--tracking-caps); text-transform: uppercase; color: var(--accent); }
.ah-note { font-size: 0.7rem; color: var(--ink-3); }
@media (max-width: 1100px) { .airflow-headline { grid-template-columns: repeat(3, minmax(0, 1fr)); row-gap: var(--space-2); } .ah-tile:nth-child(4) { border-left: 0; padding-left: 0; } }
@media (max-width: 640px) { .airflow-headline { grid-template-columns: 1fr 1fr; } .ah-tile + .ah-tile { border-left: 0; padding-left: 0; } .ah-tile:nth-child(2n) { border-left: var(--hairline) solid var(--line); padding-left: var(--space-3); } .ah-tile:nth-child(5) { grid-column: 1 / -1; border-left: 0; padding-left: 0; } .ah-value { font-size: 1.3rem; } }
/* 2560 and up: the two models and the headline column share the width, no dead margins */
@media (min-width: 2200px) {
  .v3d-body { display: grid; grid-template-columns: minmax(0, 1fr) minmax(15rem, 0.34fr); align-items: stretch; }
  .airflow-headline { grid-template-columns: 1fr; align-content: start; row-gap: 0; }
  .airflow-headline.empty { display: block; }
  .ah-tile + .ah-tile { border-left: 0; padding-left: 0; border-top: var(--hairline) solid var(--line); }
  .ah-tile { padding: var(--space-2) 0; }
  .ah-value { font-size: 1.7rem; }
  .ah-tag { border-top: var(--hairline) solid var(--line); }
}

/* the analysis panel (tailnet page only; app.js removes it elsewhere) */
.airflow-panel { flex: none; display: flex; flex-direction: column; gap: var(--space-2); scroll-margin-top: var(--space-3); }
.airflow-panel[hidden] { display: none; }
.ap-toolbar { display: flex; justify-content: space-between; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.ap-links { font-size: 0.74rem; color: var(--ink-3); }
.ap-links a { color: var(--accent); text-decoration: none; }
.ap-links a:hover { text-decoration: underline; }
.ap-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-2); }
.ap-grid .chart-box { min-height: 15rem; }
.ap-grid .chart-box.ap-wide { grid-column: span 2; }
.ap-grid .chart-box.ap-full { grid-column: 1 / -1; }
.ap-grid .chart-box .label .unit { color: var(--ink-3); font-weight: 400; font-size: 0.8em; }
.ap-grid .canvas-wrap.short { flex: none; height: 3.2rem; min-height: 3.2rem; }
/* plain (non-Chart.js) canvases: an absolutely positioned replaced element keeps its intrinsic size unless told to stretch */
#ap-regime, #ap-rose { width: 100%; height: 100%; }
.ap-grid .chart-box.ap-regime { min-height: 0; }
.ap-legend { display: flex; flex-wrap: wrap; gap: 0.3rem var(--space-3); font-size: 0.7rem; color: var(--ink-2); padding-top: var(--space-2); }
.ap-legend .swatch { display: inline-block; width: 0.9em; height: 0.9em; border-radius: 0.2em; margin-right: 0.35em; vertical-align: -0.1em; }
.ap-note { font-size: 0.7rem; color: var(--ink-3); padding-top: var(--space-1); }
.ap-table { font-size: 0.78rem; overflow: auto; flex: 1; }
.ap-table table { border-collapse: collapse; width: 100%; }
.ap-table th, .ap-table td { text-align: left; padding: 0.25em 0.5em 0.25em 0; border-bottom: var(--hairline) solid var(--line); vertical-align: top; }
.ap-table td:last-child { white-space: normal; }
.ap-table td.num, .ap-table th.num { white-space: nowrap; }
.ap-table th { color: var(--ink-2); font-weight: 500; font-size: 0.7rem; }
.ap-table td.num, .ap-table th.num { text-align: right; font-variant-numeric: tabular-nums; }
.ap-table .muted { color: var(--ink-3); }
.ap-table .flag { margin-left: 0.4em; }
.ap-table dl { display: grid; grid-template-columns: max-content 1fr; gap: 0.2em 0.8em; margin: 0; }
.ap-table dt { color: var(--ink-2); }
.ap-table dd { margin: 0; }
.ap-table .del { font: inherit; background: transparent; border: 0; color: var(--ink-3); cursor: pointer; padding: 0 0.3em; }
.ap-table .del:hover { color: var(--accent); }
.ap-form { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-1); padding-top: var(--space-2); }
.ap-form input, .ap-form select, .ap-form button { font: inherit; font-size: 0.74rem; color: var(--ink); background: var(--bg); border: var(--hairline) solid var(--line); border-radius: var(--radius-sm); padding: 0.3em 0.45em; min-width: 0; }
.ap-form input[name="time"] { grid-column: span 2; }
.ap-form input[name="notes"] { grid-column: span 3; }
.ap-form button { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); font-weight: 500; cursor: pointer; }
@media (max-width: 1100px) { .ap-grid { grid-template-columns: 1fr 1fr; } .ap-grid .chart-box.ap-wide { grid-column: span 2; } }
@media (max-width: 640px) { .ap-grid { grid-template-columns: 1fr; } .ap-grid .chart-box.ap-wide, .ap-grid .chart-box.ap-full { grid-column: auto; } .ap-form { grid-template-columns: 1fr 1fr; } .ap-form input[name="time"], .ap-form input[name="notes"] { grid-column: span 2; } }
@media (min-width: 2200px) { .ap-grid .chart-box { min-height: 20rem; } .ap-grid .chart-box.ap-regime { min-height: 0; } }

/* ==== Kiosk: one composite screen for the 4K TV, never scrolls ============================
 * html.kiosk is set by the inline script in index.html (?kiosk=1, or a 4K-class landscape viewport).
 * Top to bottom: header, readings band (5 tiles incl. Outside), the four corner cards in a row, the
 * two models side by side, the two history charts side by side. Everything in the column has either
 * its content height or a share of what is left (main has a definite height here, so a definite
 * flex basis is safe); nothing may shrink below its content. Minimum sizes at 3840x2160 (1rem = 36px):
 * primary numbers >= 64px, labels and legends >= 28px (0.8rem), chart axis text >= 24px. */
html.kiosk, html.kiosk body { height: 100%; overflow: hidden; }
/* 1rem = 0.925vw: 35.5px at 3840 (as before), 47.4px at 5120, so the 4K and 5K composites are the
 * same layout scaled (5K minimums: primary >= 85px, labels >= 37px, chart axis >= 32px). */
html.kiosk { font-size: 0.925vw; --logo-h: 5.4rem; --chart-font-size: 0.72rem; }
html.kiosk #topbar { padding-top: var(--space-2); padding-bottom: var(--space-2); }
html.kiosk .display { font-size: 1.7rem; }
html.kiosk .summary { font-size: 0.8rem; }
html.kiosk main { flex: 1 1 auto; min-height: 0; gap: var(--space-2); padding-top: var(--space-2); padding-bottom: var(--space-2); }
html.kiosk .banner { flex: none; margin-top: var(--space-2); padding: 0.3rem 0.9rem; font-size: 0.8rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
html.kiosk main > .section-heading { display: none; }
html.kiosk .overview { flex: none; grid-template-columns: repeat(5, minmax(0, 1fr)); margin-bottom: 0; }
html.kiosk .metric { padding: 0.25rem var(--space-4); gap: 0; }
html.kiosk .metric.outside-metric { display: flex; }
html.kiosk .metric-label, html.kiosk .metric-detail { font-size: 0.8rem; }
html.kiosk .metric strong { font-size: 1.9rem; line-height: 1.1; }
html.kiosk .metric .health-value { font-size: 1.85rem; padding: 0.05rem 0; }
html.kiosk .plan { flex: none; grid-template-columns: repeat(4, minmax(0, 1fr)); grid-template-rows: none; }
html.kiosk .card.pos-nw, html.kiosk .card.pos-ne, html.kiosk .card.pos-sw, html.kiosk .card.pos-se { grid-area: auto; }
html.kiosk .card.pos-outside { display: none; }
html.kiosk .card { padding-top: var(--space-1); padding-bottom: var(--space-1); }
html.kiosk .corner-header { margin-bottom: 0; }
html.kiosk .column-labels { display: none; }
html.kiosk .node { padding: 0.05rem 0; }
html.kiosk .node-name, html.kiosk .corner-name, html.kiosk .zone-code, html.kiosk .updated, html.kiosk .delta, html.kiosk .flag { font-size: 0.8rem; }
html.kiosk .reading.temp .value { font-size: 1.9rem; }
html.kiosk .reading.hum .value { font-size: 1.8rem; }
html.kiosk .v3d { flex: 1 1 auto; min-height: 0; }
html.kiosk .v3d-toolbar, html.kiosk .timebar, html.kiosk .model-note, html.kiosk .v3d > .section-heading { display: none; }
html.kiosk .models { flex: 1 1 auto; min-height: 0; }
html.kiosk .model { min-height: 0; grid-template-columns: 1fr; grid-template-rows: auto minmax(0, 1fr) auto auto; grid-template-areas: "head" "stage" "legend" "stats"; padding: var(--space-2) var(--panel-padding); gap: var(--space-1); }
html.kiosk .model-head .label { font-size: 0.95rem; }
html.kiosk .stage { aspect-ratio: auto; min-height: 0; }
html.kiosk .slabel { font-size: 0.72rem; }
html.kiosk .slabel.compass { font-size: 0.8rem; }
html.kiosk .stage-note, html.kiosk .field-warn { font-size: 0.8rem; }
html.kiosk .legend-bar { padding-top: 0; gap: 0.1rem; }
html.kiosk .legend-title, html.kiosk .legend-ticks, html.kiosk .legend-outside .tag { font-size: 0.8rem; }
html.kiosk .legend-scale { height: 0.7rem; margin-top: 1.1rem; }
/* one row: stratification, N-S, E-W, the six tier estimates (two columns wide), inside-outside */
html.kiosk .stats { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 0 var(--space-3); }
html.kiosk .stat { border-bottom: 0; padding: 0.1rem 0; }
html.kiosk .stat.hero, html.kiosk .stat.outside { display: none; }     /* the readings band already shows them */
html.kiosk .stat.tiers { grid-column: span 2; }
html.kiosk .stat.tiers .stat-value { font-size: 0.8rem; line-height: 1.3; }
html.kiosk .stat-label, html.kiosk .stat-detail { font-size: 0.8rem; }
html.kiosk .stat-value, html.kiosk .stat-value.small { font-size: 1.2rem; line-height: 1.1; }
html.kiosk .stat-detail { display: none; }
html.kiosk .charts { flex: 0 0 21vh; min-height: 0; gap: var(--space-1); }
html.kiosk .charts > .section-heading, html.kiosk .range-buttons { display: none; }
html.kiosk .chart-row { flex: 1 1 auto; min-height: 0; }
html.kiosk .chart-box { min-height: 0; padding-top: var(--space-2); }
html.kiosk .chart-box .label { margin-bottom: var(--space-1); font-size: 0.95rem; }
html.kiosk .canvas-wrap { min-height: 0; }
html.kiosk .legend-item, html.kiosk .chart-note { font-size: 0.8rem; }
html.kiosk #foot { padding-bottom: var(--space-2); font-size: 0.8rem; }

/* ==== Embed skin (data-view="embed": /embed on the public listener, framed by irawhiskey.com) ==== */
.embed-bar { display: none; }
html[data-view="embed"] { font-size: clamp(13px, 0.6vw + 9px, 18px); }
/* the embed's height is its content, never the frame's (min-height: 100% would echo the frame back) */
html[data-view="embed"], html[data-view="embed"] body { min-height: 0; height: auto; }
html[data-view="embed"] #topbar, html[data-view="embed"] #foot { display: none; }
html[data-view="embed"] .embed-bar { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--page-x) 0; flex-wrap: wrap; }
html[data-view="embed"] .embed-seal { display: none; --logo-h: 2.6rem; }
html[data-view="embed"][data-logo="1"] .embed-seal { display: block; }
html[data-view="embed"] .embed-caption { font-size: 0.95rem; font-weight: 500; color: var(--ink); }
html[data-view="embed"] .embed-bar .status-line { margin: 0 0 0 auto; }
html[data-view="embed"] main { padding-top: var(--space-2); padding-bottom: var(--space-2); }
html[data-view="embed"][data-bg="transparent"], html[data-view="embed"][data-bg="transparent"] body { background: transparent; }

/* kiosk: the headline numbers as one compact row between the models and the charts (labels >= 0.8rem,
 * i.e. 28 px at 4K / 38 px at 5K, values 1.3rem); the analysis panel and the layer toggle stay off */
/* the headline is a column beside the two models (the models keep their height), tiles stacked */
html.kiosk .v3d-body { display: grid; grid-template-columns: minmax(0, 1fr) minmax(14rem, 0.19fr); flex: 1 1 auto; min-height: 0; gap: var(--space-2); }
html.kiosk .models { min-height: 0; }
html.kiosk .airflow-headline { padding: var(--space-1) var(--panel-padding); grid-template-columns: 1fr; align-content: space-evenly; min-height: 0; overflow: hidden; }
html.kiosk .airflow-headline.empty { display: block; }
html.kiosk .ah-tile { padding: 0.15rem 0; gap: 0; border-left: 0; padding-left: 0; }
html.kiosk .ah-tile + .ah-tile { border-top: var(--hairline) solid var(--line); }
html.kiosk .ah-label, html.kiosk .ah-range { font-size: 0.8rem; }
html.kiosk .ah-value { font-size: 1.3rem; }
html.kiosk .ah-value .regime { font-size: 0.95rem; }
html.kiosk .ah-sub, html.kiosk .ah-tag { display: none; }
html.kiosk .grade { font-size: 0.66rem; }
html.kiosk .airflow-panel, html.kiosk .mode-seg { display: none; }
html.kiosk .charts { flex: 0 0 19vh; }
html[data-view="embed"] .airflow-panel { display: none; }
