/* /simulation. White ground, hairlines, two typefaces: Oxygen for structure
 * and data, Cormorant Garamond for what should read as drawn. The scene is the
 * subject; every plate is a scale bar, not an app. */

:root {
  --ink: #111; --dim: #666; --faint: #9a9a9a; --line: rgba(0,0,0,.14); --line-strong: rgba(0,0,0,.4);
  --bg: #fff; --plate: rgba(255,255,255,.86);
  --sans: 'Oxygen', system-ui, sans-serif; --serif: 'Cormorant Garamond', Georgia, serif;
}
html, body { margin: 0; padding: 0; width: 100%; height: 100%; touch-action: manipulation; background: var(--bg); color: var(--ink); overflow: hidden; font-family: var(--sans); }
button { font: inherit; color: inherit; background: none; border: none; padding: 0; cursor: pointer; }
[hidden] { display: none !important; }

/* the one renderer */
#mount, #mount iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; display: block; z-index: 1; }
#sun-overlay { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 2; pointer-events: none; }

/* loading plate */
#plate { position: fixed; inset: 0; z-index: 100; background: #fff; display: flex; flex-direction: column; align-items: center; justify-content: center; transition: opacity .8s ease; }
#plate.done { opacity: 0; pointer-events: none; }
#plate-logo { width: min(360px, 70vw); margin-bottom: 30px; }
#plate-title { font-family: var(--serif); font-weight: 300; font-size: 1.9rem; letter-spacing: .01em; }
#plate-title b, #brand h1 b { font-weight: 600; }
#plate-title i, #brand h1 i { font-style: italic; font-weight: 300; }
#plate-sub { font-size: .62rem; letter-spacing: .34em; text-indent: .34em; text-transform: uppercase; color: var(--faint); margin: 8px 0 26px; }
#plate-track { width: min(360px, 86vw); height: 1px; background: var(--line); overflow: hidden; }
#plate-bar { height: 100%; background: var(--ink); transform: scaleX(0); transform-origin: left; transition: transform .15s ease-out; }
#plate-rows { width: min(360px, 86vw); margin-top: 16px; font-size: .68rem; letter-spacing: .04em; color: var(--dim); }
/* One line per row, always (owner, 2026-09-28): the words are short enough for a phone, and should a narrower screen
   still be too tight, the name gives way before the status does, with an ellipsis, never a second line. */
#plate-rows div { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding: 3px 0; white-space: nowrap; }
#plate-rows span { flex: 0 3 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
#plate-rows em { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; font-style: normal; color: var(--faint); font-variant-numeric: tabular-nums; }
#plate-rows .done em { color: var(--ink); }
#plate-rows .done em::before { content: '·'; margin-right: 8px; color: var(--faint); }
#plate-rows .fail { color: #a33; }

/* brand */
#brand { position: fixed; left: 28px; top: 20px; z-index: 30; pointer-events: none; }
#brand h1 { margin: 0; font-family: var(--serif); font-weight: 300; font-size: 2rem; line-height: 1.05; letter-spacing: .005em; }
#logo { position: fixed; right: 28px; top: 22px; z-index: 30; display: block; line-height: 0; }
#logo img { height: 30px; width: auto; }

/* layer bar */
#layers { position: fixed; left: 28px; top: 72px; z-index: 30; display: flex; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); background: var(--plate); backdrop-filter: blur(6px); }
#layers button { padding: 9px 16px; font-size: .68rem; letter-spacing: .26em; text-indent: .26em; text-transform: uppercase; color: var(--dim); border-right: 1px solid var(--line); transition: color .15s; }
#layers button:last-child { border-right: 0; }
#layers button:hover { color: var(--ink); }
#layers button.on { color: var(--ink); box-shadow: inset 0 -2px 0 var(--ink); }

#opts { position: fixed; left: 28px; top: 112px; z-index: 30; }
#opts .dial { justify-content: flex-start; padding: 2px 0 0 9px; }
#opts .opt { display: none; align-items: center; gap: 2px; }
#opts .opt.shown { display: flex; }
#opts button { padding: 6px 9px; font-size: .62rem; letter-spacing: .18em; text-indent: .18em; text-transform: uppercase; color: var(--faint); }
#opts button:hover { color: var(--ink); }
#opts button.on { color: var(--ink); text-decoration: underline; text-underline-offset: 5px; text-decoration-thickness: 1px; }
#opts .gap { width: 14px; }
#opts .hw { padding: 6px 4px; font-size: .62rem; letter-spacing: .04em; color: var(--faint); white-space: nowrap; }
#opts button:disabled { color: #d4d4d4; cursor: default; text-decoration: none; }
/* Solar's view (Planting zones or Sunlight): one quiet select in the buttons' own type, a small chevron its only mark */
#opts select { appearance: none; -webkit-appearance: none; border: 0; border-radius: 0; background-color: transparent; cursor: pointer;
  padding: 6px 15px 6px 9px; font: inherit; font-size: .62rem; letter-spacing: .18em; text-transform: uppercase; color: var(--ink);
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-size: 3px 3px; background-repeat: no-repeat; background-position: right 6px top 54%, right 3px top 54%; }
#opts select:hover { color: var(--ink); }
#opts select:focus-visible { outline: 1px solid var(--faint); outline-offset: 2px; }
/* A download is an action, not a mode, so it never takes the `on` underline: a hairline
   box keeps it visibly a different kind of control from the metric buttons beside it. */
#opts button.dl { border: 1px solid #d8d8d8; margin-left: 4px; }
#opts button.dl:hover { border-color: var(--ink); color: var(--ink); }
#opts button.dl.busy { opacity: .45; cursor: progress; }

/* data sources. The row is the switch; the hairline cross beside it opens a deck of
 * instruments that slides out of the row and folds away again. */
#bases { position: fixed; right: 28px; top: 70px; z-index: 32; display: flex; flex-direction: column; align-items: flex-end; gap: 1px; pointer-events: none; }
#bases .row, #bases .src.open .deck { pointer-events: auto; }
#bases .src { display: flex; flex-direction: column; align-items: flex-end; }
#bases .row { display: flex; align-items: center; gap: 4px; }
#bases .tg { display: flex; align-items: center; gap: 8px; font-size: .64rem; letter-spacing: .2em; text-transform: uppercase; color: var(--faint); padding: 4px 0; }
#bases .tg::before { content: ''; width: 8px; height: 8px; border: 1px solid var(--line-strong); box-sizing: border-box; transition: background .15s; }
#bases .tg.on { color: var(--ink); }
#bases .tg.on::before { background: var(--ink); border-color: var(--ink); }
#bases .tg.busy::before { border-style: dashed; background: transparent !important; border-color: var(--line-strong) !important; }
#bases .tg i { font-style: normal; color: var(--faint); font-size: .56rem; letter-spacing: .12em; }
#bases .tg em { font-style: normal; font-variant-numeric: tabular-nums; color: var(--faint); font-size: .56rem; }
#bases .note { margin: 0 0 4px; max-width: 220px; text-align: right; color: var(--faint); font-size: .56rem; letter-spacing: .04em; line-height: 1.4; pointer-events: none; }
#bases .cells-status { white-space: nowrap; }
#bases .more { position: relative; width: 18px; height: 18px; opacity: .45; transition: opacity .15s, transform .35s cubic-bezier(.2, .8, .2, 1); }
#bases .more::before, #bases .more::after { content: ''; position: absolute; left: 50%; top: 50%; width: 9px; height: 1px; background: var(--ink); transform: translate(-50%, -50%); }
#bases .more::after { transform: translate(-50%, -50%) rotate(90deg); }
#bases .more:hover, #bases .src.open .more { opacity: 1; }
#bases .src.open .more { transform: rotate(45deg); }
#bases .deck { max-height: 0; overflow: hidden; opacity: 0; transform: translateX(10px); margin-right: 22px; padding-right: 10px; border-right: 1px solid transparent;
  transition: max-height .38s cubic-bezier(.2, .8, .2, 1), opacity .22s ease, transform .38s cubic-bezier(.2, .8, .2, 1), border-color .38s; }
#bases .src.open .deck { max-height: 140px; opacity: 1; transform: none; border-color: var(--ink); margin-bottom: 8px; }
/* a closed deck takes no width on any screen: its sliders (208-229 px) widened the right plate to 290 px against 170 of
   toggles, and the empty frosted plate read as a grey block over the scene (Shasta, 2026-10-05) */
#hud-right #bases .src:not(.open) .deck { max-width: 0; margin-right: 0; padding-right: 0; }
#bases .src.open .deck > * { animation: deck-in .42s cubic-bezier(.2, .8, .2, 1) both; }
#bases .src.open .deck > *:nth-child(2) { animation-delay: .05s; }
#bases .src.open .deck > *:nth-child(3) { animation-delay: .1s; }
@keyframes deck-in { from { opacity: 0; transform: translateX(14px); } to { opacity: 1; transform: none; } }

.dial { display: flex; align-items: center; justify-content: flex-end; gap: 10px; font-size: .54rem; letter-spacing: .2em; text-transform: uppercase; color: var(--faint); padding: 5px 0; cursor: default; }
.dial input[type=range] { -webkit-appearance: none; appearance: none; width: 112px; height: 1px; margin: 0; background: var(--line-strong); outline: none; }
.dial input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; width: 11px; height: 11px; border-radius: 50%; background: #fff; border: 1.5px solid var(--ink); cursor: pointer; }
.dial input[type=range]::-moz-range-thumb { width: 10px; height: 10px; border-radius: 50%; background: #fff; border: 1.5px solid var(--ink); cursor: pointer; }
.dial output { min-width: 28px; text-align: right; color: var(--ink); font-variant-numeric: tabular-nums; letter-spacing: .04em; }
.seg { display: flex; align-items: center; justify-content: flex-end; gap: 2px; font-size: .54rem; letter-spacing: .2em; text-transform: uppercase; color: var(--faint); padding: 5px 0; }
.seg > span { margin-right: 8px; }
.seg button { padding: 3px 6px; font-size: .56rem; letter-spacing: .16em; text-transform: uppercase; color: var(--faint); }
.seg button:hover { color: var(--ink); }
.seg button.on { color: var(--ink); box-shadow: inset 0 -1px 0 var(--ink); }
/* The LiDAR deck's ramp: the returns' own colours and the two ends they span, under the choice. */
.pramp { display: flex; align-items: center; justify-content: flex-end; gap: 8px; padding: 0 0 6px; font-size: .54rem; letter-spacing: .04em; color: var(--dim); font-variant-numeric: tabular-nums; white-space: nowrap; }
.pramp canvas { display: block; width: 112px; height: 5px; border: 1px solid var(--line); box-sizing: content-box; }

/* what a clicked surface is */
#pop { position: fixed; z-index: 40; width: 264px; padding: 13px 15px 12px; background: rgba(255, 255, 255, .95); border: 1px solid var(--line); backdrop-filter: blur(8px); font-size: .66rem; line-height: 1.55; color: var(--ink);
  box-shadow: 0 10px 34px rgba(0, 0, 0, .07); animation: pop-in .28s cubic-bezier(.2, .8, .2, 1) both; }
@keyframes pop-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
#pop .pop-x { position: absolute; right: 9px; top: 6px; font-size: 1rem; line-height: 1; color: var(--faint); }
#pop h3 { margin: 0; font-family: var(--serif); font-weight: 400; font-size: 1.25rem; line-height: 1.15; }
#pop .grp { margin-top: 2px; font-size: .54rem; letter-spacing: .22em; text-transform: uppercase; color: var(--faint); }
#pop .k { display: inline-block; padding: 0 5px; margin-left: 4px; border: 1px solid currentColor; font-size: .52rem; letter-spacing: .12em; text-transform: uppercase; line-height: 1.5; }
#pop .k.yes { color: #2f7d4d; } #pop .k.no { color: #b4553a; } #pop .k.partial { color: #9a7b1c; }
#pop dl { margin: 9px 0 0; padding-top: 8px; border-top: 1px solid var(--line); }
#pop dl div { display: flex; justify-content: space-between; gap: 10px; }
#pop dt { color: var(--dim); }
#pop dd { margin: 0; font-variant-numeric: tabular-nums; }
#pop .def { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line); font-family: var(--serif); font-size: .92rem; line-height: 1.3; color: var(--dim); }
#pop .where { margin-top: 7px; font-size: .56rem; letter-spacing: .08em; color: var(--faint); font-variant-numeric: tabular-nums; }

/* legend */
/* THE LEGEND ON THE LEFT, VERTICALLY CENTRED, NO WIDER THAN THE SOLAR BUTTON ABOVE IT AND FLUSH WITH IT (owner,
   2026-09-28): the colour bar upright with its ticks beside it; js/ui.js alignLegend sets `left` and `width` from that
   button, so it holds at every width; between 761 and 900 px, 81 px. The Surface swatches take the same box (owner
   2026-10-02: every legend one size); only a phone's swatches keep their own. */
#legend { position: fixed; left: 20px; top: 50%; transform: translateY(-50%); width: 72px; box-sizing: border-box; z-index: 30;
  padding: 7px 6px 6px; background: var(--plate); border: 1px solid var(--line); backdrop-filter: blur(6px); }
@media (max-width: 760px) { #legend.swatch { width: auto !important; max-width: 220px; } }   /* a phone: the swatches keep their box */
.lg-title { display: flex; flex-direction: column; gap: 1px; margin-bottom: 6px; }
#lg-name { font-size: .5rem; letter-spacing: .1em; line-height: 1.25; text-transform: uppercase; color: var(--dim); overflow-wrap: anywhere; }
#lg-unit { font-size: .56rem; line-height: 1.35; color: var(--faint); overflow-wrap: anywhere; white-space: pre-line; }
/* EVERY LEGEND ONE SIZE (owner 2026-10-02): the name keeps two lines and the unit one whatever their words, so a title that
   fits one line ("SOIL MOISTURE" at 81 px) no longer makes its legend shorter than the next. Above the phone's band only. */
@media (min-width: 761px) {
  #legend #lg-name { min-height: 2.5em; }
  #legend #lg-unit { min-height: 1.35em; }
  /* the Surface swatches take a ramp's width and height: names at the ticks' size, wrapping where they must */
  #legend.swatch .lg-swatches { min-width: 0; height: 180px; align-content: start; overflow: hidden; }
  #legend.swatch .lg-swatches div { font-size: .56rem; gap: 5px; line-height: 1.25; align-items: flex-start; }
  #legend.swatch .lg-swatches i { width: 8px; height: 8px; margin-top: 1px; }
}
.lg-body { display: flex; gap: 5px; }
#lg-ramp { display: block; flex: none; width: 8px; height: 180px; box-sizing: border-box; border: 1px solid var(--line); }
.lg-ticks { position: relative; flex: 1; min-width: 0; height: 180px; }
.lg-ticks span { position: absolute; left: 3px; transform: translateY(-50%); font-size: .56rem; color: var(--ink); white-space: nowrap; font-variant-numeric: tabular-nums; }
.lg-ticks span::before { content: ''; position: absolute; left: -6px; top: 50%; width: 3px; height: 1px; background: var(--line-strong); }
.lg-ticks span.seam { color: var(--faint); font-style: italic; }
.lg-ticks span.seam::before { left: -12px; width: 10px; background: var(--ink); }   /* the saturation line across the wetness strip */
.lg-note { margin-top: 7px; font-size: .56rem; letter-spacing: .06em; color: var(--faint); max-width: 100%; line-height: 1.4; }
/* The resolution a product was made at, never cut: a coarsened site says so on every screen. */
.lg-res { margin-top: 5px; font-size: .56rem; letter-spacing: .06em; color: var(--faint); max-width: 100%; line-height: 1.4; }
.lg-swatches { display: grid; gap: 3px; min-width: 176px; }
.lg-swatches div { display: flex; align-items: center; gap: 8px; font-size: .64rem; letter-spacing: .02em; color: var(--ink); }
.lg-swatches i { flex: none; width: 10px; height: 10px; border: 1px solid rgba(0, 0, 0, .12); }
.lg-swatches span { flex: 1; }
.lg-swatches em { font-style: normal; color: var(--faint); font-variant-numeric: tabular-nums; }
#lg-rose { width: 100%; height: auto; aspect-ratio: 1; margin-top: 8px; }
#lg-rose:not([hidden]) { display: block; }
/* The soil's caveats are part of what it says and are never cut; they get the room to read. */
#legend.soil .lg-note { max-width: 220px; }

/* the record's year and a Year view's metric, quiet as the speed */
#opts .xp-pick { font: inherit; font-size: .62rem; letter-spacing: .06em; color: var(--ink); border: 0; border-bottom: 1px solid var(--line); background: transparent; padding: 3px 2px; margin-left: 8px; outline: none; }
#opts .xp-pick[hidden] { display: none; }
/* a record view (Hour, Day, Year) on Wind or Water: the storm's own choices and heights step aside */
#opts .opt.xp-on [data-wfield], #opts .opt.xp-on [data-wmode], #opts .opt.xp-on [data-wspan], #opts .opt.xp-on [data-h], #opts .opt.xp-on .hw, #opts .opt.xp-on .gap { display: none; }

#foot { position: fixed; left: 28px; bottom: 9px; z-index: 30; display: flex; gap: 14px; font-size: .54rem; letter-spacing: .2em; text-transform: uppercase; color: var(--faint); }
/* Research and support, bottom right, as deepearth.dev credits them: grey and quiet, their colour on hover */
#credits { position: fixed; right: 28px; bottom: 7px; z-index: 30; display: flex; align-items: center; gap: 12px; }
#credits .cr-k { font-size: .5rem; letter-spacing: .2em; text-transform: uppercase; color: var(--faint); }
#credits .cr { position: relative; display: block; height: 22px; background: center / contain no-repeat; filter: grayscale(1); opacity: .6; transition: opacity .3s ease, filter .3s ease; }
#credits .cr:hover, #credits .cr:focus-visible { filter: none; opacity: 1; }
#credits .cr-qed { width: 135px; background-image: url(img/aff/qed-lab.svg); }
#credits .cr-nasa { width: 26px; background-image: url(img/aff/nasa.svg); }
#credits .cr-nsf { width: 92px; background-image: url(img/aff/nsf.png); }
#credits .cr-doe { width: 131px; background-image: url(img/aff/doe-sc.png); }
/* The award on hover, as deepearth.dev captions it: the sponsor, then the award, on white above the mark */
#credits .cr::after { content: attr(data-name) "\A" attr(data-award); white-space: pre; position: absolute; right: 0; bottom: calc(100% + 10px);
  padding: 7px 10px; background: #fff; border: 1px solid var(--line); box-shadow: 0 4px 16px rgba(0, 0, 0, .06);
  font-size: .62rem; line-height: 1.5; letter-spacing: .02em; color: var(--dim); opacity: 0; pointer-events: none; transition: opacity .2s ease; }
#credits .cr:hover::after, #credits .cr:focus-visible::after { opacity: 1; }
/* A phone (the owner's iPhone, 2026-09-27: "all scrunched up, lots of clashing"): the credits alone on the bottom row,
   small and unlabelled, clear of the home bar; the copyright and the data's credit stacked above them, wrapping, never
   under them. This rule had lost its @media and never applied. */
@media (max-width: 760px) {
  #credits { right: 12px; bottom: calc(6px + env(safe-area-inset-bottom)); gap: 10px; }
  #credits .cr-k { display: none; }
  #credits .cr { height: 12px; }
  #credits .cr-qed { width: 74px; } #credits .cr-nsf { width: 50px; } #credits .cr-doe { width: 70px; }
  #foot, body.site #foot { left: 12px; right: 12px; bottom: calc(24px + env(safe-area-inset-bottom)); flex-direction: column; gap: 2px;
    font-size: .48rem; letter-spacing: .14em; }
  #xp-credit { white-space: normal; line-height: 1.35; letter-spacing: .04em; }
}
/* The phone's ⓘ and its panel (placeCredits in simulation.js): the footer is left with the copyright and Google's line,
   so it sits at the bottom edge, clear of the button. */
#credits-info, #credits-panel { display: none; }
@media (max-width: 760px) {
  #foot, body.site #foot { bottom: calc(8px + env(safe-area-inset-bottom)); right: 150px; }   /* clear of SPONSORS / DATA */
  #credits-info { display: block; position: fixed; right: 12px; bottom: calc(6px + env(safe-area-inset-bottom)); z-index: 31;
    width: 24px; height: 24px; padding: 0; border-radius: 50%; border: 1px solid var(--line); background: var(--plate);
    color: var(--dim); font: italic 600 .8rem/22px var(--serif); text-align: center; cursor: pointer; }
  #credits-info[aria-expanded="true"] { color: var(--ink); border-color: var(--ink); }
  #credits-panel:not([hidden]) { display: block; position: fixed; right: 12px; bottom: calc(38px + env(safe-area-inset-bottom)); z-index: 40;
    width: min(300px, calc(100vw - 24px)); box-sizing: border-box; padding: 12px 14px; background: #fff; border: 1px solid var(--line);
    box-shadow: 0 6px 24px rgba(0, 0, 0, .08); font-size: .6rem; color: var(--dim); }
  #credits-panel #xp-credit { display: block; margin-bottom: 12px; font-size: .6rem; line-height: 1.45; letter-spacing: .03em; text-transform: none; }
  /* no hover on a phone: each sponsor's award stands under its mark */
  #credits-panel #credits { position: static; display: flex; flex-direction: column; align-items: flex-start; gap: 12px; }
  #credits-panel #credits .cr-k { display: block; margin: 0; }
  #credits-panel #credits .cr { width: auto; height: auto; padding-top: 26px; background-position: left top; background-size: auto 20px; filter: none; opacity: 1; }
  #credits-panel #credits .cr::after { position: static; display: block; opacity: 1; padding: 0; border: 0; box-shadow: none; background: none; font-size: .58rem; line-height: 1.45; }
}

@media (max-width: 900px) {
  #brand { left: 16px; top: 15px; }
  #brand h1 { font-size: 1.36rem; }
  #logo { right: 16px; top: 17px; }
  #logo img { height: 19px; }
  #layers { left: 16px; top: 52px; }
  #layers button { padding: 8px 11px; font-size: .6rem; }
  #opts { left: 16px; top: 88px; }
  #bases { right: 12px; top: 48px; }
  #bases .deck { margin-right: 20px; }
  .dial input[type=range] { width: 92px; }
  .pramp canvas { width: 92px; }
  #pop { left: 12px !important; right: 12px; width: auto; top: auto !important; bottom: 120px; }
  #legend { padding: 6px 5px 5px; }
  #lg-ramp, .lg-ticks { height: 120px; }
  .lg-ticks span { font-size: .5rem; }
  .lg-note { display: none; }
  #legend.soil .lg-note { display: block; max-width: 190px; font-size: .5rem; }
  .lg-res { max-width: 150px; font-size: .5rem; }
  #lg-rose { width: 100%; height: auto; }
  .lg-swatches { min-width: 0; }
  .lg-swatches div { font-size: .58rem; }
  .lg-swatches div:nth-child(n+7) { display: none; }
  #foot { left: 12px; bottom: 6px; }
}
@media (min-width: 761px) and (max-width: 900px) {   /* the ramp's height here, and type tight enough that six names fit it */
  #legend.swatch .lg-swatches { height: 120px; gap: 2px; }
  #legend.swatch .lg-swatches div { font-size: .5rem; line-height: 1.15; }
}
#layers button:disabled, #layers button.off { color: #c8c8c8; cursor: default; text-decoration: line-through; text-decoration-thickness: 1px; }

/* The two instrument plates, one white glass each and no rule around either: the
 * headline over the physics bar and its options, flush to one edge; the lockup over
 * the data sources. Everything inside them sits in flow, and only the physics bar
 * keeps its box. */
#hud-left, #hud-right { position: fixed; top: 16px; z-index: 32; background: var(--plate); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); }
#hud-left { left: 20px; padding: 13px 0 7px; }
#hud-right { right: 20px; padding: 12px 14px 9px; display: flex; flex-direction: column; align-items: flex-end; gap: 11px; }
#hud-left #brand, #hud-left #layers, #hud-left #opts, #hud-right #logo, #hud-right #bases { position: static; }
#hud-left #brand { padding: 0 16px 11px; }
#hud-left #layers { display: flex; background: none; -webkit-backdrop-filter: none; backdrop-filter: none; border: 1px solid var(--line); }
#hud-left #layers button { flex: 1; }
#hud-left #opts { padding: 5px 7px 0; }
#hud-left #opts .opt.shown { flex-wrap: wrap; row-gap: 2px; }
/* on a desk the options are as wide as the tabs, never wider, and a long row wraps; on a phone the panel stops at the screen */
@media (min-width: 901px) { #hud-left #opts { width: 0; min-width: 100%; box-sizing: border-box; } }
@media (max-width: 900px) { #hud-left { max-width: calc(100vw - 16px); box-sizing: border-box; } }
#hud-left #opts:not(:has(.opt.shown)):has(#field-dial[hidden]) { display: none; }
#hud-right #bases { pointer-events: auto; }
/* the lockup stands apart from the rows it heads, as the account control does on a signed-in page (owner, /bear 2026-10-22) */
#hud-right { padding-top: 16px; }
#hud-right #logo { margin-bottom: 13px; }
@media (max-width: 900px) { #hud-right { padding-top: 9px; } #hud-right #logo { margin-bottom: 5px; } }
@media (max-width: 900px) {
  #hud-left { left: 8px; top: 8px; padding: 9px 0 5px; }
  #hud-right { right: 8px; top: 8px; padding: 8px 9px 7px; gap: 7px; }
  #hud-left #brand { padding: 0 10px 8px; }
  #hud-left #brand h1 { font-size: 1.22rem; }
  #hud-right #logo img { height: 15px; }
  #hud-right #bases .tg { font-size: .56rem; letter-spacing: .14em; }
  #hud-left #layers button { padding: 7px 9px; }
}
/* A phone holds both plates side by side only if the left one yields: it keeps clear
 * of the right one's width, and an option row breaks at its gap. */
@media (max-width: 560px) {
  /* One width from the first frame: sized by its content, the plate grew when a simulation's options appeared and
   * Wind slid from x 135 to 238 under a second tap, which landed on Water (real iPhone, U1, 2026-10-11). */
  #hud-left { width: calc(100vw - 162px); max-width: calc(100vw - 162px); }
  #hud-left #brand h1 { font-size: 1.04rem; }
  #hud-left #layers button { padding: 7px 4px; letter-spacing: .12em; text-indent: .12em; }
  #hud-left #opts .opt { flex-wrap: wrap; }
  #hud-left #opts .gap { flex-basis: 100%; height: 0; }
  #hud-right #logo img { height: 12px; }
  #hud-right #bases .tg i { display: none; }
  #hud-right #bases .src:not(.open) .deck { max-width: 0; margin-right: 0; padding-right: 0; }   /* a closed deck takes no width */
  /* The quiet lines under the toggles (the survey's status, the twin's note) wrap inside the width the
   * left plate leaves the right one, so the right plate never grows over the physics bar (X1, 23:19Z). */
  #hud-right #bases .cells-status, #hud-right #bases .note { white-space: normal; max-width: 118px; }
  /* The physics bar keeps every tab inside its frame. */
  #hud-left #layers { box-sizing: border-box; max-width: 100%; }
  #hud-left #layers button { letter-spacing: .06em; text-indent: .06em; min-width: 0; }
  /* The legend narrow and against the edge, so the opening view of a site or a campus stays clear of it. */
  #legend { padding: 5px 4px 4px; }
  #lg-name { font-size: .5rem; letter-spacing: .14em; }
  .lg-res { max-width: 100%; }
  /* the wetness strip holds two units and the saturation line: taller, so its seven labels stand apart */
  #legend.wet .lg-ticks span { font-size: .56rem; }
}

/* ── a platform site ─────────────────────────────────────────────────────── */
/* The way back to the project list, under the headline: a label, not a button. */
#back { display: block; margin-top: 7px; font-family: var(--sans); font-size: .56rem; letter-spacing: .26em; text-transform: uppercase; color: var(--faint); text-decoration: none; pointer-events: auto; }
#back::before { content: '\2190\00a0'; }
#back:hover { color: var(--ink); }
/* A physics ordered and still being computed reads as coming, not as struck out. */
#layers button.pending, #layers button.pending:disabled { color: var(--faint); text-decoration: none; font-style: italic; }
#attrib { letter-spacing: .06em; text-transform: none; }
#xp-credit { letter-spacing: .06em; text-transform: none; }
/* A still: the site alone, with the tiles' attribution on its own at the lower right. */
body.still #back, body.still #order { display: none; }
body.still #attrib { position: fixed; right: 10px; bottom: 8px; z-index: 30; font-family: var(--sans); font-size: 10px; color: var(--dim); background: rgba(255, 255, 255, .78); padding: 2px 6px; }
body.still #attrib:empty { display: none; }

/* The order in progress: one white glass plate at the lower left, the same hairline
 * track as the loading plate, one bar per product, and what comes next. */
/* No backdrop blur: over a busy scene its soft edge reads as a smudge beside the plate. */
#order { position: fixed; left: 20px; bottom: 30px; z-index: 31; width: 300px; padding: 13px 16px 12px; background: rgba(255, 255, 255, .94); }
#order .or-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
#order .or-name { font-family: var(--serif); font-size: 1.18rem; line-height: 1.15; }
#order .more { position: relative; flex: none; width: 18px; height: 18px; opacity: .45; transition: opacity .15s, transform .35s cubic-bezier(.2, .8, .2, 1); }
#order .more::before, #order .more::after { content: ''; position: absolute; left: 50%; top: 50%; width: 9px; height: 1px; background: var(--ink); transform: translate(-50%, -50%); }
#order .more::after { transform: translate(-50%, -50%) rotate(90deg); }
#order .more:hover, #order.open .more { opacity: 1; }
#order.open .more { transform: rotate(45deg); }
#order .or-note { margin-top: 6px; font-family: var(--serif); font-style: italic; font-size: .92rem; line-height: 1.3; color: var(--dim); }
#order .or-track { height: 1px; margin-top: 11px; background: var(--line); overflow: hidden; }
#order .or-bar { height: 100%; background: var(--ink); transform: scaleX(0); transform-origin: left; transition: transform .6s cubic-bezier(.2, .8, .2, 1); }
#order .or-read { display: flex; justify-content: space-between; gap: 10px; margin-top: 7px; font-size: .62rem; letter-spacing: .08em; color: var(--dim); font-variant-numeric: tabular-nums; }
#order .or-pct { color: var(--ink); letter-spacing: .04em; }
#order .or-now { margin-top: 3px; font-size: .62rem; letter-spacing: .02em; color: var(--faint); min-height: .9rem; }
#order .or-eta.note { font-style: italic; text-align: right; }
#order .or-clock { margin-top: 1px; font-size: .56rem; letter-spacing: .03em; color: var(--faint); font-variant-numeric: tabular-nums; }
#order .or-clock:empty { display: none; }
#order .or-cancel { margin-top: 6px; font-size: .58rem; color: var(--ink); }
#order .or-cancel[hidden] { display: none; }
#order .or-cancel p { margin: 0 0 5px; line-height: 1.4; }
#order .or-cancel button { font: inherit; letter-spacing: .08em; text-transform: uppercase; background: none; color: var(--ink); border: 1px solid var(--ink); padding: 4px 8px; cursor: pointer; }
#order .or-cancel button:disabled { opacity: .5; cursor: default; }
#order .or-deck { max-height: 0; overflow: hidden; opacity: 0; transition: max-height .4s cubic-bezier(.2, .8, .2, 1), opacity .25s ease; }
#order.open .or-deck { max-height: 560px; opacity: 1; overflow-y: auto; }   /* several quality notes outgrow the deck: scrolled, never cut */
#order .or-sub { grid-column: 1 / -1; flex-basis: 100%; margin-top: 0; font-size: .55rem; line-height: 1.35; letter-spacing: .02em; color: var(--faint); font-variant-numeric: tabular-nums; }
/* The rows share one set of columns (subgrid), so a longer word ("queued for a GPU") widens the word
 * column for every row and the bars stay aligned. Without subgrid, the fixed 92px column holds it. */
#order .or-rows { margin-top: 10px; padding-top: 9px; border-top: 1px solid var(--line); display: grid; grid-template-columns: minmax(0, 1fr) 70px max-content; gap: 6px 10px; }
#order .or-row { display: grid; grid-column: 1 / -1; grid-template-columns: minmax(0, 1fr) 70px 92px; grid-template-columns: subgrid; align-items: center; gap: 2px 10px; font-size: .62rem; letter-spacing: .03em; color: var(--dim); }
#order .or-row em { font-style: normal; text-align: right; white-space: nowrap; color: var(--faint); font-variant-numeric: tabular-nums; }
#order .or-t { height: 1px; background: var(--line); overflow: hidden; }
#order .or-t i { display: block; height: 100%; background: var(--ink); transform-origin: left; transition: transform .6s cubic-bezier(.2, .8, .2, 1); }
#order .or-row.done { color: var(--ink); }
#order .or-row.done em { color: var(--ink); }
/* An italic word leans past its box; the deck's overflow:hidden cut the last letter off
   a word at the plate's right edge on a phone. The pad keeps the lean inside. */
/* A row that is not under way names its state in italic ("on hold", "not started", "paused"), each as
 * quiet as the next. The alarm is the operator's, in /admin. A percentage and "ready" stay upright. */
#order .or-row:not(.done) em.w { font-style: italic; padding-right: .15em; }
#order .or-h { margin-top: 11px; padding-top: 9px; border-top: 1px solid var(--line); font-size: .52rem; letter-spacing: .3em; text-transform: uppercase; color: var(--faint); }
#order .or-nx { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0 10px; margin-top: 5px; font-size: .62rem; color: var(--dim); }
#order .or-nx em { font-style: normal; color: var(--faint); white-space: nowrap; }
#order .or-nx em.unplanned { font-style: italic; }
#order .or-nx .or-sub { margin-top: 1px; }
#order.complete .or-now { color: var(--ink); }
@media (max-width: 900px) {
  /* Above the footer, which on a phone stacks the copyright over Google's attribution. */
  body.site #foot { flex-direction: column; gap: 1px; right: 150px; }   /* clear of SPONSORS / DATA: Google's line ran under them (Balboa, 390 px) */
  body.site #attrib { font-size: .5rem; line-height: 1.35; }
  #order { left: 8px; right: 8px; bottom: 52px; width: auto; padding: 10px 12px 9px; }
  /* A phone has no room for the plate beside a physics' legend and timeline: it steps
     aside while one is open and returns with the site view. */
  body.tl-on #order { display: none; }
  #order .or-name { font-size: 1rem; }
  #order.open .or-deck { max-height: 42vh; overflow-y: auto; }
  /* The legend and the plate share the bottom of a phone and never overlap: over a
     folded plate the legend stands just above it (--order-h is the plate's height, kept
     by js/order.js); while the plate's details are open the legend steps aside, and
     folding the plate brings it back. With a physics open the plate is the one aside. */
  body:not(.tl-on):has(#order.open) #legend { display: none; }
  /* A still stands Google's attribution above the copyright line, not across it. */
  body.still #attrib { left: 12px; right: 12px; bottom: 22px; }
}

/* ───────────────────────── the plant palette tab ─────────────────────────
   Its own column on the right, because a palette is a list a reader scans and
   compares; the click popup the other tabs use cannot hold one. It sits where
   the legend sits and the two never show together: the palette carries its own
   words, so legend() returns null for this product. */
.pl-hint { padding: 6px 10px; font-size: .62rem; color: var(--dim); background: var(--plate);
           border: 1px solid var(--line); backdrop-filter: blur(6px); }

#palette { position: fixed; right: 28px; top: 132px; bottom: 118px; z-index: 30; width: 286px;
           display: flex; flex-direction: column; padding: 12px 0 0; background: var(--plate);
           border: 1px solid var(--line); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); }
#palette[hidden] { display: none; }
.pl-head { padding: 0 14px 9px; border-bottom: 1px solid var(--line); }
.pl-where { display: block; font-family: var(--serif); font-size: 1.16rem; line-height: 1.2; color: var(--ink); }
.pl-cond { display: block; margin-top: 3px; font-size: .54rem; letter-spacing: .2em;
           text-transform: uppercase; color: var(--faint); }
.pl-reason { margin: 9px 14px 0; font-size: .63rem; line-height: 1.5; color: var(--dim); }
.pl-reason:empty { display: none; }
/* The list scrolls; the head and the footnote do not, so what the palette IS stays on screen
   while a reader runs down twenty species. */
.pl-list { flex: 1; min-height: 0; overflow-y: auto; padding: 10px 14px 4px;
           display: flex; flex-direction: column; gap: 18px; }   /* cards, not rows: they need air */
/* A SPECIES CARD, NOT A 42 px THUMBNAIL. The photo was 42 px square beside its name, which is a
   favicon: a reader cannot tell two shrubs apart at that size, and choosing plants is the one task
   this panel exists for. ecodash.ai shows the same species at 300 px square (`--large-dim`), with
   the image itself the link to GBIF, and the photographs layer in this very viewer opens a frame
   far larger still. The panel's content column is 258 px (286 less 14 either side), so a full-width
   square lands within a fifth of ecodash.ai's and is the largest this panel can honestly give.
   The card stacks, photo over name, for the same reason ecodash.ai's does: at this width a name
   beside the photo would have 40 px to live in. */
.pl-sp { display: block; }
.pl-sp .pl-photo { display: block; position: relative; }
.pl-sp img, .pl-sp .ph { width: 100%; aspect-ratio: 1 / 1; height: auto; display: block; }
.pl-sp img { object-fit: cover; background: rgba(0,0,0,.05); opacity: 0; transition: opacity .35s ease; }
.pl-sp img.on { opacity: 1; }
.pl-sp .ph { background: repeating-linear-gradient(135deg, transparent 0 5px, var(--line) 5px 6px); }
/* The photo is the link, so it has to look like one under a pointer and be reachable by keyboard. */
.pl-sp .pl-photo:hover img { opacity: .86; }
.pl-sp .pl-photo:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.pl-sp > div { margin-top: 7px; }
.pl-nm { font-family: var(--serif); font-style: italic; font-size: .92rem; line-height: 1.2; color: var(--ink); }
.pl-why { font-size: .52rem; letter-spacing: .12em; text-transform: uppercase; color: var(--faint); margin-top: 2px; }
.pl-less { font-size: .52rem; letter-spacing: .12em; text-transform: uppercase; color: var(--dim); margin-top: 2px; }
/* A species admitted with a miss rather than a match reads quieter, so a reader can see at a
   glance which of the twenty actually fit and which are the best of a short field. */
.pl-sp.pl-relaxed .pl-nm { color: var(--dim); }
.pl-foot { margin: 0; padding: 8px 14px 10px; border-top: 1px solid var(--line);
           font-size: .54rem; line-height: 1.5; color: var(--faint); }
.pl-foot:empty { display: none; }

@media (max-width: 860px) {
  /* On a phone the panel is the bottom third rather than a column: a 286 px rail leaves no
     site to click on. */
  #palette { right: 12px; left: 12px; width: auto; top: auto; bottom: 96px; max-height: 42vh; }
}

/* ───────────────────── a tab that needs a subscription ─────────────────────
   Greyed by the same three-state grammar the rest of the platform uses, with the
   marker that says why. It stays PRESSABLE: a disabled control that does nothing
   reads as broken, and nobody buys a feature they cannot find. */
#layers button.locked { color: var(--faint); cursor: pointer; position: relative; }
#layers button.locked:hover { color: var(--dim); }
.tag-pro { position: absolute; top: 2px; right: 4px; font-size: .42rem; letter-spacing: .14em;
           text-transform: uppercase; color: var(--faint); line-height: 1; }

.pro-modal { position: fixed; inset: 0; z-index: 90; display: flex; align-items: center;
             justify-content: center; padding: 24px; background: rgba(255,255,255,.62);
             -webkit-backdrop-filter: blur(7px); backdrop-filter: blur(7px); }
.pro-modal[hidden] { display: none; }
.pro-modal-box { max-width: 400px; background: #fff; border: 1px solid var(--line-strong);
                 padding: 24px 26px 20px; }
.pro-modal-box h2 { font-family: 'Cormorant Garamond', Georgia, serif; font-weight: 300;
                    font-size: 1.45rem; line-height: 1.15; margin-bottom: 10px; color: var(--ink); }
.pro-modal-box p { font-size: .8rem; line-height: 1.6; color: var(--dim); }
.pro-modal-actions { display: flex; gap: 10px; margin-top: 20px; align-items: center; }
.pro-btn { font-family: 'Oxygen', sans-serif; font-size: .6rem; letter-spacing: .2em;
           text-indent: .2em; text-transform: uppercase; padding: .6rem 1.1rem;
           border: 1px solid var(--line-strong); background: none; color: var(--ink);
           cursor: pointer; text-decoration: none; }
.pro-btn:hover { border-color: var(--ink); }
.pro-btn-go { border-color: var(--ink); }
.pro-btn-go:hover { background: var(--ink); color: #fff; }

/* ───────────────────── one time control, one panel grammar (owner, 2026-09-24) ─────────────────────
   Time lives in the timeline alone: the scale (Light, Hour, Day, Month, Year) sits above the transport and the date,
   drawn as the physics bar is drawn (a hairline box, the chosen one ink with a rule under it). The panel at the top
   left carries only what is not time: the physics, a wind height for the animation, the opacity and the method note.
   The older per-physics buttons stay in the page as the state the scale reports, and are not shown. */
#opts [data-smode], #opts [data-xview], #opts [data-xmetric], #opts .xp-year, #opts [data-wfield], #opts [data-wspan],
#opts [data-wspan-gap], #opts [data-wmode], #opts .gap, #opts .hw { display: none !important; }
#hud-left #opts { display: flex; flex-wrap: wrap; align-items: center; column-gap: 6px; }
#hud-left #opts .opt.shown { flex-basis: 100%; flex-wrap: nowrap; }
#hud-left #opts .opt.shown:not(:has(> :not([hidden]):not([data-smode]):not([data-xview]):not([data-xmetric]):not(.xp-year):not([data-wfield]):not([data-wspan]):not([data-wspan-gap]):not([data-wmode]):not(.gap):not(.hw):not(#sim-info))) { display: none; }
#hud-left #opts #sim-info { margin-left: 4px; }
#opts [data-h] { padding: 6px 7px; }

@media (max-width: 900px) { #hud-left #opts .opt.shown { flex-wrap: wrap; } }
/* the order plate stands just above the time player (--tl-top: its top edge's distance from the window's bottom, kept by
   js/ui.js syncTime) */
body.tl-on #order { bottom: calc(var(--tl-top, 114px) + 10px); }
/* a phone: the opacity and the method note share one line */
@media (max-width: 560px) { #hud-left #opts .dial input[type=range] { width: 70px; } }
/* the tower's share of a Year's hours, one line per driver, under the ramp (a phone too) */
.lg-share { margin-top: 6px; padding-top: 5px; border-top: 1px solid var(--line); font-size: .54rem; letter-spacing: .06em; color: var(--dim); line-height: 1.5; }
@media (max-width: 900px) { .lg-share { font-size: .5rem; } }

/* ONE TIME (owner, 2026-09-25): Solar's view choice, Water's measured storms and its what-if, and the one line a
   simulation says where it holds nothing at the clock */
#opts [data-sview] i { font-style: normal; text-transform: none; letter-spacing: .03em; text-indent: 0; margin-left: 2px; }
#opts .w-storm { display: inline-flex; align-items: center; gap: 6px; padding: 0 0 0 9px; font-size: .56rem; letter-spacing: .18em; text-transform: uppercase; color: var(--faint); white-space: nowrap; }
#opts .w-storm[hidden] { display: none; }
#opts .w-storm select { font: inherit; font-size: .62rem; letter-spacing: .04em; text-transform: none; color: var(--ink); border: 0; border-bottom: 1px solid var(--line); background: transparent; padding: 3px 2px; outline: none; }
#opts #w-whatif { margin-left: 6px; }
#opts #w-whatif[hidden] { display: none; }
#hud-left #opts .sim-empty { flex-basis: 100%; margin: 6px 0 2px 9px; max-width: 320px; font-size: .68rem; line-height: 1.55; color: var(--dim); }
#hud-left #opts .sim-empty[hidden] { display: none; }
#hud-left #opts .sim-empty button { padding: 0; margin-left: 4px; font-size: inherit; letter-spacing: 0; text-indent: 0; text-transform: none; color: var(--ink); text-decoration: underline; text-decoration-color: var(--line-strong, #bbb); text-underline-offset: 3px; }
#hud-left #opts .sim-empty button[hidden] { display: none; }
/* the graph's detail in the info note (graphDetail): the agreement, the drivers, the second tower, the carry */
#sim-note .gd { margin-top: 11px; padding-top: 9px; border-top: 1px solid var(--line); }
#sim-note .gd p { margin: 5px 0 0; font-size: .64rem; line-height: 1.55; color: var(--dim); }
/* a second quantity in one legend (a storm's ponded water over its hour's soil water): a row under the ramp, hairline above */
.lg-also { margin-top: 8px; padding-top: 6px; border-top: 1px solid var(--line); width: 100%; }
.lg-also-t { display: flex; flex-direction: column; gap: 1px; margin-bottom: 4px; }
#lg-also-name { font-size: .54rem; letter-spacing: .2em; text-transform: uppercase; color: var(--dim); }
#lg-also-unit { font-size: .6rem; color: var(--faint); }
#lg-also-ramp { display: block; width: 100%; height: 6px; }
.lg-also-ends { display: flex; justify-content: space-between; margin-top: 3px; font-size: .6rem; color: var(--ink); font-variant-numeric: tabular-nums; }
@media (max-width: 560px) { .lg-also { width: 100%; margin-top: 6px; padding-top: 4px; } #lg-also-name { font-size: .48rem; letter-spacing: .14em; } .lg-also-ends, #lg-also-unit { font-size: .52rem; } }
/* A phone with a simulation open: the timeline owns the bottom, so the copyright, the data's credit and the research and
   support marks step aside and return with the site's own view (owner's iPhone, 2026-09-27: all scrunched up) */
@media (max-width: 760px) {
  body.tl-on #foot, body.tl-on #credits { display: none; }
}
#legend .lg-note:empty, #legend .lg-share:empty { display: none; }   /* no commentary under the legend (owner 2026-09-28) */
/* SPONSORS / DATA (js/credits.js): two quiet words at the floor's right, and their panel above them, set as the method
   note is (#sim-note): a small-caps group, a serif name, plain lines */
/* on white, as the page's other controls: over a dark splat or a colored map the two words were lost (owner 2026-09-30) */
#cb { position: fixed; right: 20px; bottom: 5px; z-index: 31; display: flex; gap: 18px; padding: 2px 8px; background: rgba(255, 255, 255, .94); }
#cb button { padding: 2px 0; font-size: .56rem; letter-spacing: .22em; text-indent: .22em; text-transform: uppercase; color: var(--faint); border-bottom: 1px solid transparent; transition: color .15s, border-color .15s; }
#cb button:hover, #cb button[aria-expanded="true"] { color: var(--ink); }
#cb button.pin { border-bottom-color: var(--ink); }
#cb-pop { position: fixed; right: 20px; bottom: 30px; z-index: 41; box-sizing: border-box; max-height: calc(100vh - 150px); overflow-y: auto;
  padding: 16px 20px 18px; background: rgba(255, 255, 255, .97); border: 1px solid var(--line); box-shadow: 0 10px 34px rgba(0, 0, 0, .08); }
#cb-pop[hidden] { display: none; }
#cb-pop .x { position: absolute; right: 10px; top: 7px; padding: 0; font-size: 1.05rem; line-height: 1; color: var(--faint); }
#cb-pop .x:hover { color: var(--ink); }
#cb-pop .grp { font-size: .54rem; letter-spacing: .22em; text-transform: uppercase; color: var(--faint); }
#cb-pop h3 { margin: 4px 0 10px; font-family: var(--serif); font-weight: 400; font-size: 1.2rem; line-height: 1.15; }
#cb-pop.cb-sponsors { width: 620px; }
#cb-pop .cb-marks { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 26px 32px; align-items: center; margin: 18px 0 6px; }
#cb-pop .cb-mark { justify-self: start; width: var(--w); max-width: 100%; height: 66px; background: left center / contain no-repeat; padding: 0;
  filter: grayscale(1); opacity: .75; transition: filter .25s, opacity .25s; }
#cb-pop .cb-mark:hover, #cb-pop .cb-mark.on { filter: none; opacity: 1; }
#cb-pop .cb-mark[data-k="nasa"] { height: 76px; }
#cb-pop .cb-mark[data-k="uf"] { height: 48px; }
#cb-pop .cb-mark[data-k="nebius"] { height: 32px; }
#cb-pop .cb-mark[data-k="google"] { height: 44px; }
.cb-card { margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--line); }
.cb-card[hidden] { display: none; }
.cb-card.side { position: fixed; z-index: 41; box-sizing: border-box; width: 300px; margin: 0; padding: 16px 20px 18px;
  background: rgba(255, 255, 255, .97); border: 1px solid var(--line); box-shadow: 0 10px 34px rgba(0, 0, 0, .08); }
.cb-card h3 { margin: 0 0 4px; font-family: var(--serif); font-weight: 400; font-size: 1.2rem; line-height: 1.15; }
.cb-card p { margin: 0; font-size: .68rem; line-height: 1.55; color: var(--dim); }
.cb-card p.award { margin-top: 6px; font-family: var(--serif); font-style: italic; font-size: .92rem; color: var(--ink); }
.cb-card p.go { margin-top: 8px; font-size: .56rem; letter-spacing: .22em; text-transform: uppercase; }
#cb-pop a, .cb-card a { color: var(--ink); text-decoration: underline; text-decoration-color: var(--line-strong); text-underline-offset: 3px; }
#cb-pop a:hover, .cb-card a:hover { text-decoration-color: var(--ink); }
#cb-pop.cb-data { width: 440px; }
#cb-pop .ly { border-top: 1px solid var(--line); }
#cb-pop .ly:last-child { border-bottom: 1px solid var(--line); }
#cb-pop .ly > button { display: flex; width: 100%; justify-content: space-between; align-items: center; padding: 9px 0 8px; font-size: .56rem; letter-spacing: .22em; text-transform: uppercase; color: var(--dim); }
#cb-pop .ly > button::after { content: '+'; font-size: .8rem; letter-spacing: 0; color: var(--faint); transition: transform .25s ease; }
#cb-pop .ly > button:hover, #cb-pop .ly.open > button { color: var(--ink); }
#cb-pop .ly.open > button::after { transform: rotate(45deg); }
#cb-pop .ly .bd { display: none; padding: 0 0 12px; }
#cb-pop .ly.open .bd { display: block; }
#cb-pop .cb-it + .cb-it { margin-top: 10px; }
#cb-pop .cb-it .nm { font-family: var(--serif); font-size: .92rem; line-height: 1.25; color: var(--ink); }
#cb-pop .cb-it .by { margin-top: 1px; font-size: .66rem; line-height: 1.45; color: var(--ink); }
#cb-pop .cb-it .dt { margin-top: 1px; font-size: .62rem; line-height: 1.45; color: var(--dim); }
#cb-pop .cb-it .lc { margin-top: 2px; font-size: .5rem; letter-spacing: .18em; text-transform: uppercase; color: var(--faint); }
@media (max-width: 900px) {
  #cb { right: 6px; bottom: calc(6px + env(safe-area-inset-bottom)); gap: 14px; padding: 2px 6px; }
  #cb-pop, #cb-pop.cb-sponsors, #cb-pop.cb-data { left: 8px; right: 8px; width: auto; bottom: calc(30px + env(safe-area-inset-bottom)); max-height: 66vh; padding: 14px 16px 16px; }
  #cb-pop .cb-marks { gap: 18px 20px; }
  #cb-pop .cb-mark { height: 44px; }
  #cb-pop .cb-mark[data-k="nasa"] { height: 54px; }
}
/* the logo strip and the phone's i are replaced by SPONSORS / DATA */
#credits, #credits-info, #credits-panel { display: none !important; }
#xp-credit { display: none; }   /* the flux towers are credited under DATA (js/credits.js) */

/* Water's named swatches under the ramp (owner 2026-09-30): the flood's returns it stood above, the sealed ground that
   sheds all its water, the ground with no soil */
.lg-mark { display: flex; flex-direction: column; gap: 4px; margin-top: 8px; padding-top: 6px; border-top: 1px solid var(--line); width: 100%; font-size: .54rem; letter-spacing: .14em; text-transform: uppercase; color: var(--dim); }
.lg-mark[hidden] { display: none; }
.lg-mark div { display: flex; align-items: center; gap: 6px; line-height: 1.3; }
.lg-mark i { flex: none; width: 10px; height: 10px; border-radius: 50%; }
@media (max-width: 560px) { .lg-mark { font-size: .48rem; letter-spacing: .1em; margin-top: 6px; padding-top: 4px; } }
/* the three water views on one line of a phone, as Solar's two are */
@media (max-width: 560px) { #hud-left #opts .opt.shown [data-wview] { padding-left: 5px; padding-right: 5px; letter-spacing: .1em; text-indent: .1em; } }

/* ───────────── THE TIME PLAYER (owner 2026-09-30 17:03Z): Solar's alone, one row, one long oval ─────────────
   Two pods and the play button between them. The pods' outer ends are fully round and their inner ends are cut
   concave around the button, so the outer edges of three controls add up to one horizontal oval. Left pod: the
   moment, "June 23, 2024 2:34 PM", month, day and time each our own picker, the part the colors do not aggregate
   over dimmed. Right pod: the span the colors aggregate over (Radiance). Equal pods: play centred. */
:root { --pod: #f1f1ef; --pod-h: 40px; --play: 54px; --cut: 32px; }
#timeline { position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%); z-index: 30; display: grid;
  grid-template-columns: 1fr 1fr; align-items: center; width: max-content; max-width: calc(100vw - 24px); }
#timeline[hidden] { display: none; }
.tp-pod { position: relative; display: flex; align-items: stretch; justify-content: center; height: var(--pod-h); background: var(--pod); }
.tp-left { border-radius: calc(var(--pod-h) / 2) 0 0 calc(var(--pod-h) / 2); padding: 0 calc(var(--cut) + 4px) 0 8px;
  -webkit-mask: radial-gradient(circle var(--cut) at 100% 50%, transparent calc(var(--cut) - .5px), #000 var(--cut));
  mask: radial-gradient(circle var(--cut) at 100% 50%, transparent calc(var(--cut) - .5px), #000 var(--cut)); }
.tp-right { border-radius: 0 calc(var(--pod-h) / 2) calc(var(--pod-h) / 2) 0; padding: 0 8px 0 calc(var(--cut) + 4px);
  -webkit-mask: radial-gradient(circle var(--cut) at 0 50%, transparent calc(var(--cut) - .5px), #000 var(--cut));
  mask: radial-gradient(circle var(--cut) at 0 50%, transparent calc(var(--cut) - .5px), #000 var(--cut)); }
.tp-seg { position: relative; display: flex; align-items: center; padding: 0 12px; white-space: nowrap; color: var(--ink); }
.tp-seg + .tp-seg::before { content: ''; position: absolute; left: 0; top: 11px; bottom: 11px; width: 1px; background: rgba(0, 0, 0, .1); }
/* the moment: the date in the serif, the time in the sans; a part outside the aggregated span dimmed */
.tp-date { font-family: var(--serif); font-size: 1.14rem; font-weight: 400; letter-spacing: .01em; }
.tp-time { font-size: .9rem; font-weight: 300; font-variant-numeric: tabular-nums; }
.tp-date .dim, .tp-time .dim { color: #b3b3b3; transition: color .2s; }
/* month, day and time: each its own words, a tap opening our picker over them (owner, 2026-10-11: no system selectors) */
.tp-pk { height: 28px; align-self: center; padding: 0 4px; border-radius: 8px; transition: background .15s; }
.tp-pk:hover, .tp-pk.open { background: rgba(0, 0, 0, .055); }
.tp-date .tp-pk + .tp-pk { margin-left: 2px; }
#tl-year { margin-left: -4px; }   /* ", 2024" against the day, the button's padding not between them */
/* the picker: a white card over the player, the chosen in ink */
#tp-pick { position: absolute; bottom: calc(100% + 12px); z-index: 5; padding: 14px 14px 12px; background: #fff; border-radius: 16px;
  box-shadow: 0 10px 34px rgba(0, 0, 0, .14), 0 0 0 1px rgba(0, 0, 0, .05); color: var(--ink); animation: pk-in .16s ease-out; }
#tp-pick[hidden] { display: none; }
@keyframes pk-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.pk-h { margin: 0 0 10px; font-family: var(--serif); font-size: 1.08rem; text-align: center; }
.pk-g { display: grid; gap: 4px; }
.pk-m { grid-template-columns: repeat(4, 54px); }
.pk-d { grid-template-columns: repeat(7, 32px); }
#tp-pick button { height: 32px; border-radius: 16px; font-size: .8rem; font-weight: 300; font-variant-numeric: tabular-nums; transition: background .12s, color .12s; }
#tp-pick button:hover { background: var(--pod); }
#tp-pick button.on { background: var(--ink); color: #fff; font-weight: 400; }
.pk-m button { font-size: .62rem !important; letter-spacing: .16em; text-indent: .16em; text-transform: uppercase; }
.pk-d em { font-style: normal; font-size: .54rem; letter-spacing: .14em; line-height: 22px; text-align: center; color: var(--faint); }
.pk-r { display: flex; align-items: center; gap: 2px; }
.pk-r + .pk-r { margin-top: 3px; }
.pk-l { width: 36px; flex: none; font-size: .54rem; letter-spacing: .16em; text-transform: uppercase; color: var(--faint); }
.pk-t button { width: 30px; height: 30px !important; }
.pk-n { margin-top: 9px !important; padding-top: 9px; border-top: 1px solid rgba(0, 0, 0, .08); }
.pk-n button { width: 52px; }
@media (max-width: 560px) {
  #tp-pick { padding: 12px 10px 10px; }
  .pk-t button { width: 24px; height: 28px !important; font-size: .72rem !important; }
  .pk-l { width: 30px; }
  .pk-n button { width: 46px; }
}
/* SHADOWS: the clock and play alone, the button on the pod's own end. PLANTING ZONES: no play, the pods one oval. */
#timeline.solo { grid-template-columns: max-content; padding-right: calc(var(--play) / 2); }
#timeline.solo #tl-play { left: calc(100% - var(--play) / 2); }
#timeline .tp-right[hidden], #tl-play[hidden] { display: none; }
#timeline.noplay .tp-left, #timeline.noplay .tp-right { -webkit-mask: none; mask: none; padding: 0 8px; }
#timeline.solo.noplay { padding-right: 0; }
#timeline.solo.noplay .tp-left { border-radius: calc(var(--pod-h) / 2); }
#timeline.noplay .tp-right::before { content: ''; position: absolute; left: 0; top: 11px; bottom: 11px; width: 1px; background: rgba(0, 0, 0, .1); }
/* play: the one filled control, centred between the pods */
#tl-play { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: var(--play); height: var(--play); border-radius: 50%;
  display: grid; place-items: center; background: var(--ink); color: #fff; padding: 0; box-shadow: 0 2px 10px rgba(0, 0, 0, .12); transition: transform .15s; }
#tl-play:hover { transform: translate(-50%, -50%) scale(1.04); }
#tl-play i { display: block; width: 0; height: 0; margin-left: 4px; border-left: 15px solid #fff; border-top: 9.5px solid transparent; border-bottom: 9.5px solid transparent; }
#tl-play.on i { width: 13px; height: 17px; margin-left: 0; box-sizing: border-box; border: 0; border-left: 4.5px solid #fff; border-right: 4.5px solid #fff; }
/* the span the colors aggregate over: five words, the chosen one in ink over a dot */
.tl-scale { gap: 2px; padding: 0 4px 0 10px; }
.tl-scale button { position: relative; height: 100%; padding: 0 8px; font-size: .56rem; letter-spacing: .2em; text-indent: .2em; text-transform: uppercase; color: var(--faint); transition: color .15s; }
.tl-scale button:hover { color: var(--ink); }
.tl-scale button.on { color: var(--ink); }
.tl-scale button.on::after { content: ''; position: absolute; left: 50%; bottom: 6px; width: 4px; height: 4px; margin-left: -2px; border-radius: 50%; background: var(--ink); }
.tl-scale button[hidden] { display: none; }
.tl-scale-pick { display: none; }
/* a tablet or a phone: the same row, smaller; the scale a native menu showing the chosen span */
@media (max-width: 960px) {
  :root { --pod-h: 36px; --play: 48px; --cut: 29px; }
  #timeline { bottom: calc(var(--floor-h, 26px) + 10px); }
  .tp-seg { padding: 0 9px; }
  .tp-date { font-size: 1rem; }
  .tp-time { font-size: .8rem; }
  #tl-play i { border-left-width: 13px; border-top-width: 8px; border-bottom-width: 8px; margin-left: 3px; }
  #tl-play.on i { width: 12px; height: 15px; border-left-width: 4px; border-right-width: 4px; }
  .tl-scale { display: none; }
  .tl-scale-pick { display: flex; align-items: center; position: relative; height: 100%; border-radius: 0; padding: 0 12px; font-size: .56rem; letter-spacing: .18em; text-transform: uppercase; color: var(--ink); cursor: pointer; }
  .tl-scale-pick::after { content: ''; width: 4px; height: 4px; margin-left: 6px; border-right: 1px solid var(--ink); border-bottom: 1px solid var(--ink); transform: translateY(-2px) rotate(45deg); }
  .pk-s { grid-template-columns: repeat(5, auto); }
  .pk-s button { padding: 0 10px; font-size: .58rem !important; letter-spacing: .16em; text-indent: .16em; text-transform: uppercase; }
}
@media (max-width: 380px) {
  :root { --pod-h: 34px; --play: 44px; --cut: 27px; }
  .tp-seg { padding: 0 7px; }
  .tp-date { font-size: .92rem; }
  .tp-time { font-size: .74rem; }
}
/* play above both pods: their concave ends lie under it */
#tl-play { z-index: 2; }
/* a phone: Water's three views on one line */
@media (max-width: 420px) { #opts [data-wview] { padding: 6px 5px; letter-spacing: .12em; text-indent: .12em; } }
/* A PHONE'S LEGEND NEVER COVERS THE SCENE (coordinator 2026-09-30 18:33Z): a band across the screen just under the
   controls, on the white the framing keeps there: the name and unit on one line, the ramp laid flat between its two
   named ends. js/ui.js alignLegend sets its top from the controls' bottom; the class swatches keep their box. */
.lg-h { display: none; }
@media (max-width: 760px) {
  #legend:not(.swatch) { left: 16px !important; right: 16px; width: auto !important; transform: none; bottom: auto;
    padding: 0; background: none; border: 0; -webkit-backdrop-filter: none; backdrop-filter: none; }
  #legend:not(.swatch) .lg-title { flex-direction: row; align-items: baseline; gap: 8px; margin-bottom: 3px; }
  #legend:not(.swatch) #lg-name { font-size: .5rem; letter-spacing: .16em; overflow-wrap: normal; white-space: nowrap; }
  #legend:not(.swatch) #lg-unit { font-size: .56rem; white-space: nowrap; }
  #legend:not(.swatch) .lg-body, #legend:not(.swatch) #lg-rose { display: none !important; }
  #legend:not(.swatch) .lg-h { display: flex; align-items: center; gap: 8px; font-size: .56rem; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
  #lg-h-ramp { flex: 1; min-width: 0; height: 6px; }
}
/* a phone: each simulation's views on one row at every width (Water's three measured at 390 px with Oxygen loaded) */
@media (max-width: 560px) {
  #hud-left #opts .opt.shown { flex-wrap: nowrap; }
  #opts [data-wview], #opts [data-sview] { padding: 6px 4px; font-size: .56rem; letter-spacing: .1em; text-indent: .1em; white-space: nowrap; }
}

/* Plan view and export (js/plan-export.js): a deck like the bases', and the sheet's frame over the scene */
#bases .src.open .plan-deck { max-height: 460px; }
#bases .plan-deck [hidden] { display: none !important; }
#bases .plan-deck select { font: inherit; font-size: .56rem; letter-spacing: .14em; text-transform: uppercase; color: var(--ink); background: transparent; border: 0; padding: 3px 0; text-align: right; cursor: pointer; max-width: 150px; }
#bases .plan-deck input { font: inherit; font-size: .62rem; letter-spacing: .04em; color: var(--ink); background: transparent; border: 0; border-bottom: 1px solid var(--line-strong); width: 120px; margin-right: 6px; padding: 2px 0; text-transform: none; }
#bases .plan-deck button:disabled { opacity: .35; cursor: default; }
#bases .plan-note { max-width: 240px; margin: 2px 0 0; }
#plan-frame { position: fixed; z-index: 20; pointer-events: none; outline: 1px solid var(--ink); box-shadow: 0 0 0 200vmax rgba(255, 255, 255, .55); }
#plan-frame span { position: absolute; right: 0; top: calc(100% + 7px); font-size: .54rem; letter-spacing: .18em; text-transform: uppercase; color: var(--ink); white-space: nowrap; }

/* THE DATA PANEL, ONE COLUMN (owner, 2026-10-11: "simple, visible, elegant opening and closing, minimal, effective";
   the fonts varied, one row had no +, the rows started where their words ended). Every row is one grid: its box, its
   name, its detail right-aligned in the same type a shade lighter, and the open control in a column every row keeps.
   A row's controls open beneath its name on a hairline; one open at a time. Plan export, the one action, sits below a rule. */
#hud-right #bases { width: 236px; align-items: stretch; gap: 0; }
#hud-right #bases .src { align-items: stretch; }
#hud-right #bases .row { display: grid; grid-template-columns: 1fr 18px; align-items: center; column-gap: 4px; }
#hud-right #bases .tg { display: grid; grid-template-columns: 9px auto 1fr auto; column-gap: 10px; align-items: center; width: 100%;
  text-align: left; font-size: .6rem; letter-spacing: .18em; padding: 5px 0; }
#hud-right #bases .tg::before { width: 9px; height: 9px; }
#hud-right #bases .tg i, #hud-right #bases .tg em { font-size: .6rem; letter-spacing: .18em; text-transform: uppercase; color: var(--faint); opacity: .8; }
#hud-right #bases .tg i { justify-self: end; }
#hud-right #bases .tg.on i, #hud-right #bases .tg.on em { color: var(--ink); opacity: .45; }
#hud-right #bases .tg em:empty { display: none; }
#hud-right #bases .more.none { pointer-events: none; opacity: 0; }
#hud-right #bases .more.none::before, #hud-right #bases .more.none::after { display: none; }
#hud-right #bases .note { text-align: left; max-width: none; margin: 0 0 4px 19px; }
#hud-right #bases #plan-src { border-top: 1px solid var(--line); margin-top: 7px; padding-top: 6px; }
/* the controls beneath the name: a hairline on their left, labels left and controls right, opening downward */
#hud-right #bases .deck { margin: 0 0 0 4px; padding: 0 0 0 15px; border-left: 1px solid transparent; border-right: 0; transform: translateY(-3px); max-width: none;
  transition: max-height .42s cubic-bezier(.2, .8, .2, 1), opacity .26s ease, transform .42s cubic-bezier(.2, .8, .2, 1), border-color .42s, margin-bottom .42s; }
#hud-right #bases .src:not(.open) .deck { max-width: none; margin-right: 0; padding-right: 0; }
#hud-right #bases .src.open .deck { border-color: var(--ink); transform: none; margin: 1px 0 9px 4px; }
#hud-right #bases .deck .seg, #hud-right #bases .deck .dial, #hud-right #bases .deck .pramp { justify-content: flex-end; }
#hud-right #bases .deck .seg > span, #hud-right #bases .deck .dial > span { margin-right: auto; }
#hud-right #bases .deck .dial input[type=range] { width: 104px; }
#hud-right #bases .src.open .deck > * { animation: deck-down .42s cubic-bezier(.2, .8, .2, 1) both; }
@keyframes deck-down { from { opacity: 0; transform: translateY(-5px); } to { opacity: 1; transform: none; } }
#hud-right #bases .plan-deck select { text-align: right; }
/* THE PANEL AS WIDE AS ITS NAMES (owner, 2026-10-11: drop "bare earth", "Google", "mesh"; "Plan" is "Export"; the left
   boxes and the right + column still aligned, the empty column gone so the two sit tight). A row's controls keep their
   width and open to the left beneath it, the panel's right edge held; a note wraps to the names' width. */
#hud-right #bases { width: max-content; }
#hud-right #bases .tg i { display: none; }
#hud-right #bases .tg { grid-template-columns: 9px auto auto; justify-content: start; }
#hud-right #bases .row { column-gap: 16px; }
#hud-right #bases .note { width: 0; min-width: calc(100% - 19px); }
#hud-right #bases .deck, #hud-right #bases .src.open .deck { width: 0; min-width: 100%; padding-left: 0; border-left: 0; margin-left: 0; overflow-x: visible; overflow-y: clip; }   /* clipped only as it opens downward: its controls reach left of the names */
#hud-right #bases .deck > * { box-sizing: border-box; width: 222px; margin-left: calc(100% - 222px); padding-left: 15px; box-shadow: inset 1px 0 0 transparent; transition: box-shadow .42s; }
#hud-right #bases .src.open .deck > * { box-shadow: inset 1px 0 0 var(--ink); background: var(--bg); }   /* past the panel's edge */
/* ONE SURFACE (owner, 2026-10-20, asked twice): a translucent row over the translucent panel read as a near-opaque patch
   wherever they overlapped; with a choice open the panel and its rows are one opaque plate */
#hud-right:has(#bases .src.open) { background: var(--bg); }
@media (max-width: 760px) {
  #hud-right #bases { width: max-content; }
  #hud-right #bases .row { column-gap: 12px; }
  #hud-right #bases .deck > * { width: 172px; margin-left: calc(100% - 172px); padding-left: 11px; }
}
@media (max-width: 760px) {
  #hud-right #bases { width: max-content; }   /* tight to its names, as on a desktop (owner, 2026-10-11) */
  #hud-right #bases .tg { font-size: .56rem; letter-spacing: .14em; column-gap: 8px; }
  #hud-right #bases .tg i { display: none; }
  #hud-right #bases .deck .dial input[type=range] { width: 58px; }
  /* a phone's column is narrower than a row of choices: they wrap under their label, never past the panel's edge */
  #hud-right #bases .deck { min-width: 100%; }
  #hud-right #bases .deck .seg { flex-wrap: wrap; row-gap: 1px; letter-spacing: .1em; }
  #hud-right #bases .deck .seg button { padding: 3px 4px; letter-spacing: .1em; }
  #hud-right #bases .deck .dial { gap: 6px; letter-spacing: .1em; }
}
/* EXPORT, CONDENSED (owner, 2026-10-18: the final button was covered): the settings as summary lines a press unfolds,
   the body scrolling within the screen, the Export buttons pinned at the panel's foot, the legend out of the way */
#bases .src.open .plan-deck { display: flex; flex-direction: column; max-height: 460px; overflow: hidden; }
#bases .plan-deck .plan-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; padding-right: 2px; }
#bases .plan-deck .plan-go { flex: none; display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 6px 10px; padding: 8px 0 2px; border-top: 1px solid var(--line); margin-top: 4px; background: inherit; }
#bases .plan-deck .plan-x { font: inherit; font-size: .58rem; letter-spacing: .18em; text-transform: uppercase; color: #fff; background: var(--ink); border: 1px solid var(--ink); border-radius: 4px; padding: 7px 12px; cursor: pointer; }
#bases .plan-deck .plan-xa { font: inherit; font-size: .54rem; letter-spacing: .16em; text-transform: uppercase; color: var(--ink); background: transparent; border: 1px solid var(--line-strong); border-radius: 4px; padding: 6px 10px; cursor: pointer; }
#bases .plan-deck .plan-go .plan-note { flex-basis: 100%; text-align: right; margin: 0; }
#bases .plan-deck .plan-sum { display: flex; align-items: baseline; justify-content: flex-end; gap: 8px; width: 100%; padding: 5px 0; font: inherit; font-size: .56rem; letter-spacing: .14em; text-transform: uppercase; color: var(--ink); background: transparent; border: 0; border-bottom: 1px dotted var(--line-strong); cursor: pointer; text-align: right; }
#bases .plan-deck .plan-sum .ps-v { flex: 1 1 auto; text-transform: none; letter-spacing: .04em; font-size: .64rem; }
#bases .plan-deck .plan-sum .ps-k { flex: none; color: var(--faint); }
#bases .plan-deck .plan-sum[aria-expanded="true"] .ps-k { transform: rotate(45deg); }
#bases .plan-deck .plan-set { padding: 2px 0 4px; }
body.plan-open #legend { visibility: hidden; }
#bases .plan-deck .plan-pick { margin: 3px 0; }
#bases .plan-deck .ck-sel-plan .ck-sel-k { width: 44px; text-align: left; }
#bases .plan-deck .ck-sel-plan.open .ck-sel-opts { max-height: 260px; overflow-y: auto; }
/* PLANT's spot label (owner, 2026-10-18): it wraps rather than cut "Outside the modelled site ..." short, and stands clear
   of the first cards */
body.ck #plant .pf-head .pf-where, #plant .pf-head .pf-where { white-space: normal; overflow: visible; text-overflow: clip; line-height: 1.5; }
body.ck #plant .pf-head:not(.bare) { padding-bottom: 12px; }
/* the spot label on its own line above the cards on a desktop too (run5: it sat behind the first row's top edge) */
html body.ck #plant .pf-head:not(.bare) { position: relative; z-index: 3; margin-bottom: 10px; padding-bottom: 4px; }
/* PLANT's habitat opacity dial, at the foot of its legend (js/plant-habitat.js): its label and value on one line, the
   track under them at the legend's own width, so the dial never widens the legend (owner, 2026-10-21) */
#legend .habitat-dial { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 6px; margin: 8px 0 2px; font-size: .5rem; letter-spacing: .16em; text-transform: uppercase; color: var(--dim); }
#legend .habitat-dial input[type=range] { order: 3; flex: 1 0 100%; min-width: 0; width: 100%; margin: 0; }
#legend .habitat-dial b { font-weight: 400; text-align: right; color: var(--ink); }
body.ck.ck-plant #legend { max-width: 128px; }
/* Copy view: an operator's camera view as text, for the order page's screenshots (CFG.capture_view) */
#view-copy { position: fixed; right: 28px; bottom: 46px; z-index: 40; padding: 4px 11px; font: 400 11px/1.4 Oxygen, sans-serif;
  letter-spacing: .02em; color: #3a3a38; background: rgba(255, 255, 255, .88); border: 1px solid rgba(0, 0, 0, .18);
  border-radius: 999px; cursor: pointer; }
#view-copy:hover { border-color: rgba(0, 0, 0, .5); color: #0d0d0d; }
