/* Kompressor — dark, dense, forge-shop. */

:root {
  --bg:        #0c1016;
  --panel:     #131923;
  --panel-2:   #1a2231;
  --line:      #26304180;
  --line-solid:#263041;
  --ink:       #e6ecf5;
  --ink-dim:   #93a2b8;
  --ink-faint: #63728a;
  --hot:       #ff6a13;
  --hot-soft:  #ffb066;
  --cool:      #38bdf8;
  --good:      #34d399;
  --warn:      #fbbf24;
  --bad:       #f87171;
  --radius:    12px;
  --mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

/* Half the elements here are flex or grid containers, and `display` on those
   beats the UA stylesheet's [hidden] rule. Without this, hiding anything by
   setting `hidden` silently does nothing. */
[hidden] { display: none !important; }

html { color-scheme: dark; }

body {
  margin: 0;
  background:
    radial-gradient(1100px 520px at 12% -8%, #1d2637 0%, transparent 62%),
    radial-gradient(800px 400px at 100% 0%, #241a12 0%, transparent 55%),
    var(--bg);
  color: var(--ink);
  font: 15px/1.55 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  min-height: 100vh;
}

h1, h2, h3 { margin: 0; font-weight: 650; letter-spacing: -0.01em; }
p { margin: 0; }

.mono { font-family: var(--mono); font-size: 0.88em; }

/* ---------------------------------------------------------------- topbar */

.topbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px; flex-wrap: wrap;
  padding: 22px clamp(16px, 4vw, 44px) 18px;
  border-bottom: 1px solid var(--line);
}
.brand { display: flex; align-items: center; gap: 14px; }
.brand h1 { font-size: 25px; letter-spacing: 0.02em; }
.brand p { color: var(--ink-dim); font-size: 13.5px; max-width: 62ch; }
.anvil { filter: drop-shadow(0 2px 6px #ff6a1340); }

.topbar-right { display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }
.topbar-right .segmented { width: 172px; }
.caps { display: flex; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }

/* Hidden on a wide screen: there the badges cost nothing and reading them is
   free. It is only the stacked phone layout that cannot afford them. */
.caps-summary {
  display: none; cursor: pointer; font: 11px/1 var(--mono);
  padding: 6px 10px; border-radius: 999px;
  color: var(--good); background: #0e1a14; border: 1px solid #34d39955;
}
.caps-summary:hover { border-color: var(--good); }

.presetbar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 10px 12px; margin-bottom: 16px;
  background: #0f141d; border: 1px solid var(--line-solid); border-radius: 10px;
}
.presetbar > span {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-dim);
}
.presetbar select { width: auto; min-width: 210px; flex: 0 1 auto; }
.presetbar .spacer { flex: 1; }

.deliver { display: flex; gap: 8px; flex-wrap: wrap; }
.deliver button { flex: 1 1 auto; }

.qr-out { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
#qrHolder canvas {
  width: 100%; max-width: 420px; image-rendering: pixelated;
  border-radius: 6px; border: 1px solid var(--line-solid);
}

#dataText { height: 120px; font: 13px/1.5 system-ui, sans-serif; resize: vertical; }
#dataPeek {
  margin-top: 12px; max-height: 260px; white-space: pre-wrap; overflow-wrap: anywhere;
}
#dataCanvas { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
#dataArmorText { height: 150px; font: 11.5px/1.45 var(--mono); resize: vertical; white-space: pre; }
#dataQrHolder canvas {
  width: 100%; max-width: 380px; image-rendering: pixelated;
  border-radius: 6px; border: 1px solid var(--line-solid);
}
.topbar-right .segmented { width: 230px; }

.rx-actions { display: flex; gap: 8px; margin-top: 12px; }
.rx-actions .forge { width: auto; padding-inline: 26px; }
#rxText { height: 170px; font: 11.5px/1.45 var(--mono); resize: vertical; white-space: pre; }

/* One cell per block, so a gap is visible rather than described. */
.blockmap { display: flex; flex-wrap: wrap; gap: 3px; margin-top: 12px; }
.blockmap i {
  width: 13px; height: 13px; border-radius: 3px; display: block;
  background: var(--good); font-style: normal;
}
.blockmap i.missing { background: var(--bad); }
.blockmap i.repaired { background: var(--warn); }
.pill {
  font: 600 11.5px/1 var(--mono);
  padding: 6px 10px; border-radius: 999px;
  border: 1px solid var(--line-solid); color: var(--ink-dim);
  background: #0f141d; white-space: nowrap;
}
.pill.ok   { color: var(--good); border-color: #34d39955; background: #0e1a17; }
.pill.no   { color: var(--bad);  border-color: #f8717155; background: #1a1113; }

/* ---------------------------------------------------------------- layout */

main {
  max-width: 1240px; margin: 0 auto;
  padding: 24px clamp(16px, 4vw, 44px) 80px;
  display: flex; flex-direction: column; gap: 20px;
}

.panel {
  background: var(--panel);
  border: 1px solid var(--line-solid);
  border-radius: var(--radius);
  padding: 20px;
}
.panel-head { margin-bottom: 16px; position: relative; }
.panel-head h2 { font-size: 15px; text-transform: uppercase; letter-spacing: 0.09em; color: var(--hot-soft); }
.panel-head p  { color: var(--ink-dim); font-size: 13.5px; margin-top: 4px; max-width: 78ch; }
.panel-head .ghost { position: absolute; top: -4px; right: 0; }
.panel-head .segmented { position: absolute; top: -4px; right: 0; width: 128px; }
.panel-head h2 .optional {
  margin-left: 8px; font-size: 10px; letter-spacing: 0.08em;
  color: var(--ink-faint); border: 1px solid var(--line-solid);
  padding: 2px 7px; border-radius: 999px; vertical-align: 2px;
}

/* ---------------------------------------------------------------- fields */

.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field > span { font-size: 12px; color: var(--ink-dim); letter-spacing: 0.04em; text-transform: uppercase; }
.field > span b { color: var(--ink); font-family: var(--mono); font-weight: 600; }
.field.inline { flex-direction: row; align-items: center; gap: 8px; }
.field.inline > span { text-transform: none; }
/* Replacing three style="" attributes. The hosted copy runs under the site's
   CSP, where style-src 'self' drops inline style attributes without an error. */
.field.grow { flex: 1; }
.field.spaced { margin-top: 16px; }

input[type=number], input[type=text], select, textarea {
  width: 100%;
  background: #0d121a;
  color: var(--ink);
  border: 1px solid var(--line-solid);
  border-radius: 8px;
  padding: 9px 10px;
  font: inherit;
  font-size: 14px;
}
input:focus-visible, select:focus-visible, textarea:focus-visible, button:focus-visible,
.dropzone:focus-visible {
  outline: 2px solid var(--hot); outline-offset: 2px;
}
select { cursor: pointer; }

.with-unit { position: relative; display: flex; align-items: center; }
.with-unit input { padding-right: 46px; }
.with-unit em {
  position: absolute; right: 10px; font-style: normal;
  font: 600 11px/1 var(--mono); color: var(--ink-faint);
  text-transform: uppercase; letter-spacing: 0.06em; pointer-events: none;
}

input[type=range] { width: 100%; accent-color: var(--hot); }

.check {
  display: flex; align-items: center; gap: 8px;
  font-size: 13.5px; color: var(--ink-dim); cursor: pointer;
}
.check input { accent-color: var(--hot); width: 15px; height: 15px; }
.check em { font-style: normal; color: var(--ink-faint); font-size: 12.5px; }

.note { color: var(--ink-faint); font-size: 12.5px; line-height: 1.5; }
.two-up { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

button {
  font: inherit; cursor: pointer; border-radius: 8px;
  border: 1px solid var(--line-solid);
  background: var(--panel-2); color: var(--ink);
  padding: 9px 14px;
  transition: background 0.12s, border-color 0.12s, transform 0.06s;
}
button:hover { background: #232d3f; border-color: #33405a; }
button:active { transform: translateY(1px); }
button:disabled { opacity: 0.45; cursor: not-allowed; }

.ghost { background: transparent; color: var(--ink-dim); }
.ghost:hover { color: var(--ink); background: var(--panel-2); }
.small { padding: 6px 10px; font-size: 13px; }

.forge {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  width: 100%; padding: 13px 18px;
  font-weight: 650; letter-spacing: 0.04em; text-transform: uppercase; font-size: 14px;
  color: #1a0f05;
  background: linear-gradient(180deg, #ffb066, var(--hot));
  border: 1px solid #ff8c42;
  box-shadow: 0 6px 22px -8px #ff6a1399;
}
.forge:hover { background: linear-gradient(180deg, #ffc189, #ff7a2b); border-color: #ffa05c; }
.forge img { filter: brightness(0.25) saturate(0); }

.segmented { display: flex; gap: 0; border: 1px solid var(--line-solid); border-radius: 8px; overflow: hidden; }
.segmented button {
  flex: 1; border: 0; border-radius: 0; background: #0d121a;
  color: var(--ink-dim); font-size: 13px; padding: 9px 8px;
}
.segmented button.on { background: var(--hot); color: #1a0f05; font-weight: 620; }
.segmented button:disabled { opacity: 0.35; cursor: not-allowed; background: #0d121a; }
.segmented button:disabled.on { background: #0d121a; color: var(--ink-faint); }
.segmented.tiny button { padding: 6px 8px; font-size: 12px; }

.chips { display: flex; gap: 6px; flex-wrap: wrap; }
.chip {
  padding: 5px 11px; font-size: 12.5px; border-radius: 999px;
  background: #0d121a; color: var(--ink-dim); border: 1px solid var(--line-solid);
}
.chip.on { background: var(--cool); color: #041018; border-color: var(--cool); font-weight: 620; }

/* ---------------------------------------------------------------- budget */

.budget-grid {
  display: grid; gap: 14px;
  grid-template-columns: minmax(240px, 2fr) repeat(2, minmax(140px, 1fr)) minmax(190px, 1.2fr);
  align-items: end;
}
.budget-readout {
  background: linear-gradient(160deg, #23180e, #14100c);
  border: 1px solid #4a3520;
  border-radius: 10px; padding: 10px 14px;
  display: flex; flex-direction: column; gap: 1px;
}
.budget-readout .label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.09em; color: var(--hot-soft); }
.budget-readout strong { font: 700 25px/1.15 var(--mono); color: #ffd9b0; }
.budget-readout .sub { font-size: 12px; color: var(--ink-faint); font-family: var(--mono); }
#linkNote { margin-top: 12px; }

/* ---------------------------------------------------------------- drop */

.dropzone {
  border: 2px dashed #2f3c52; border-radius: var(--radius);
  padding: 46px 20px; text-align: center; cursor: pointer;
  color: var(--ink-dim); background: #0e131b;
  transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.dropzone:hover, .dropzone.over { border-color: var(--hot); background: #17120d; color: var(--ink); }
.dropzone svg { color: var(--ink-faint); margin-bottom: 10px; }
.dropzone:hover svg, .dropzone.over svg { color: var(--hot); }
.dropzone .hint { font-size: 12.5px; color: var(--ink-faint); margin-top: 6px; }

/* ---------------------------------------------------------------- work */

.work-grid { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(280px, 1fr); gap: 22px; }

.stage-wrap {
  background:
    repeating-conic-gradient(#161c26 0% 25%, #11161e 0% 50%) 50% / 18px 18px;
  border: 1px solid var(--line-solid); border-radius: 10px;
  padding: 10px; display: flex; justify-content: center;
}
.stage {
  position: relative; width: 100%; max-height: 62vh;
  aspect-ratio: 16 / 9; user-select: none; touch-action: none;
  margin: 0 auto;
}
.stage canvas, .stage video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  display: block; object-fit: fill; border-radius: 4px; background: #000;
}

.crop-scrim {
  position: absolute; inset: 0; z-index: 2;
  background: rgba(6, 9, 14, 0.68);
  pointer-events: none;
}
.cropbox {
  position: absolute; cursor: move;
  border: 1.5px solid #fff;
  z-index: 3;
}
.cropbox.dragging { border-color: var(--hot); }
.crop-thirds {
  position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(to right, transparent 33.33%, #ffffff42 33.33% calc(33.33% + 1px), transparent calc(33.33% + 1px),
                    transparent 66.66%, #ffffff42 66.66% calc(66.66% + 1px), transparent calc(66.66% + 1px)),
    linear-gradient(to bottom, transparent 33.33%, #ffffff42 33.33% calc(33.33% + 1px), transparent calc(33.33% + 1px),
                    transparent 66.66%, #ffffff42 66.66% calc(66.66% + 1px), transparent calc(66.66% + 1px));
}
.crop-handle {
  position: absolute; width: 14px; height: 14px;
  background: #fff; border: 1px solid #0c1016; border-radius: 3px;
}
.cropbox.dragging .crop-handle { background: var(--hot); }
.crop-nw { left: -7px;  top: -7px;    cursor: nwse-resize; }
.crop-ne { right: -7px; top: -7px;    cursor: nesw-resize; }
.crop-sw { left: -7px;  bottom: -7px; cursor: nesw-resize; }
.crop-se { right: -7px; bottom: -7px; cursor: nwse-resize; }
.crop-n  { left: 50%; top: -7px;    transform: translateX(-50%); cursor: ns-resize; }
.crop-s  { left: 50%; bottom: -7px; transform: translateX(-50%); cursor: ns-resize; }
.crop-w  { top: 50%; left: -7px;    transform: translateY(-50%); cursor: ew-resize; }
.crop-e  { top: 50%; right: -7px;   transform: translateY(-50%); cursor: ew-resize; }

/* Audio has no spatial crop, so the overlay comes off entirely rather than
   sitting inert over a waveform and inviting a drag that does nothing. */
.stage.no-crop .cropbox, .stage.no-crop .crop-scrim { display: none; }

#audioEl { width: 100%; margin-top: 12px; }

.stage-tools { display: flex; align-items: center; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
.stage-tools .spacer { flex: 1; }
.cropinfo {
  margin-top: 8px; font: 12.5px/1.5 var(--mono); color: var(--ink-faint);
}

.trim { margin-top: 16px; border-top: 1px solid var(--line); padding-top: 14px; }
.trim-head {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 12px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-dim);
}
.trim-head .mono { color: var(--cool); text-transform: none; letter-spacing: 0; }
.trim-actions { display: flex; gap: 8px; flex-wrap: wrap; }

/* The trim strip.
   `touch-action: none` is the load-bearing line: without it a horizontal drag
   on a phone is claimed by the scroll view and the handle never moves, which is
   most of what made the old pair of sliders unusable on a touch screen. */
.trimstrip {
  position: relative; height: 64px; margin: 10px 0 12px;
  border-radius: 10px; overflow: hidden;
  border: 1px solid var(--line-solid); background: #0a0e14;
  touch-action: none; user-select: none; -webkit-user-select: none;
  cursor: pointer;
}
@media (max-width: 700px) { .trimstrip { height: 76px; } }

.trimstrip-film { position: absolute; inset: 0; display: block; }

/* Everything outside the selection is dimmed rather than hidden, so the clip
   you are cutting away stays visible and the cut stays reversible by eye. */
.trimstrip-shade {
  position: absolute; top: 0; bottom: 0; background: rgba(6, 9, 14, 0.72);
  pointer-events: none;
}
.trimstrip-shade.left { left: 0; }
.trimstrip-shade.right { right: 0; }

.trimstrip-selection {
  position: absolute; top: 0; bottom: 0;
  border-top: 3px solid var(--hot); border-bottom: 3px solid var(--hot);
  pointer-events: none;
}

/* Wide enough for a thumb. The visible bracket is narrower than the hit area,
   which is what makes a 12-pixel-looking handle actually catchable. */
.trimstrip-handle {
  position: absolute; top: -3px; bottom: -3px; width: 34px;
  pointer-events: auto; cursor: ew-resize; touch-action: none;
  display: flex; align-items: center; justify-content: center;
}
.trimstrip-handle.left  { left: -17px; }
.trimstrip-handle.right { right: -17px; }
.trimstrip-handle::before {
  content: ""; width: 14px; height: 100%;
  background: var(--hot); border-radius: 4px;
}
.trimstrip-handle::after {
  content: ""; position: absolute; width: 2px; height: 18px;
  background: #0a0e14; border-radius: 2px;
}
.trimstrip-handle:focus-visible::before { box-shadow: 0 0 0 3px var(--hot-soft); outline: none; }
.trimstrip-handle:focus { outline: none; }
.trimstrip.dragging .trimstrip-handle::before { background: var(--hot-soft); }

.trimstrip-playhead {
  position: absolute; top: 0; bottom: 0; width: 2px; margin-left: -1px;
  background: #fff; box-shadow: 0 0 6px rgba(255,255,255,0.6);
  opacity: 0; pointer-events: none; transition: opacity 0.15s;
}

.controls-col { display: flex; flex-direction: column; gap: 16px; }
.control-group {
  background: #0f141d; border: 1px solid var(--line-solid);
  border-radius: 10px; padding: 14px; display: flex; flex-direction: column; gap: 12px;
}
.control-group h3 {
  font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.09em; color: var(--cool);
}
.target-readout {
  font: 12.5px/1.6 var(--mono); color: var(--ink-dim);
  background: #0a0e14; border: 1px solid var(--line); border-radius: 8px; padding: 10px;
  white-space: pre-line;
}

.progress { display: flex; flex-direction: column; gap: 6px; }
.progress .bar { height: 7px; background: #0a0e14; border-radius: 999px; overflow: hidden; border: 1px solid var(--line-solid); }
.progress .bar > div { height: 100%; width: 0; background: linear-gradient(90deg, var(--hot), var(--hot-soft)); transition: width 0.12s; }
.progress span { font: 12px var(--mono); color: var(--ink-dim); }

/* ---------------------------------------------------------------- result */

.result-grid { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(300px, 1fr); gap: 22px; }
.compare { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.compare figure { margin: 0; display: flex; flex-direction: column; gap: 7px; }
.compare figcaption {
  font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-dim);
  display: flex; justify-content: space-between; gap: 8px;
}
.compare figcaption .mono { color: var(--ink); text-transform: none; letter-spacing: 0; }
.thumb {
  background: #05080c; border: 1px solid var(--line-solid); border-radius: 8px;
  min-height: 130px; display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.thumb img, .thumb video { max-width: 100%; max-height: 44vh; display: block; }

.contact-sheet { display: flex; flex-direction: column; gap: 10px; width: 100%; padding: 8px; }
.contact-sheet figure { margin: 0; display: flex; flex-direction: column; gap: 4px; }
.contact-sheet img { width: 100%; display: block; border-radius: 4px; }
.contact-sheet figcaption { font: 11px var(--mono); color: var(--ink-faint); }

.result-stats { display: flex; flex-direction: column; gap: 14px; }
#statsList, #statsMore, #rxStats, #dataStats { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: 7px 16px; align-items: baseline; }
#statsList dt, #statsMore dt, #rxStats dt, #dataStats dt { font-size: 12px; color: var(--ink-dim); text-transform: uppercase; letter-spacing: 0.05em; }
#statsList dd, #statsMore dd, #rxStats dd, #dataStats dd { margin: 0; font-family: var(--mono); font-size: 13px; text-align: right; }
#statsList dd.good, #statsMore dd.good, #rxStats dd.good, #dataStats dd.good { color: var(--good); }
#statsList dd.warn, #statsMore dd.warn, #rxStats dd.warn, #dataStats dd.warn { color: var(--warn); }
#statsList dd.bad, #statsMore dd.bad, #rxStats dd.bad, #dataStats dd.bad { color: var(--bad); }
.result-actions { display: flex; flex-direction: column; gap: 8px; }

.armor { display: flex; flex-direction: column; gap: 8px; }
.armor-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.armor-head .field.inline span { font-size: 12px; color: var(--ink-dim); white-space: nowrap; }
.armor-head input { width: 92px; }
#armorText { height: 190px; font: 11.5px/1.45 var(--mono); resize: vertical; white-space: pre; }

/* ---------------------------------------------------------------- misc */

.log {
  margin: 0; max-height: 190px; overflow: auto;
  font: 12px/1.6 var(--mono); color: var(--ink-dim);
  background: #0a0e14; border: 1px solid var(--line); border-radius: 8px; padding: 12px;
  white-space: pre-wrap;
}
.log .t { color: var(--ink-faint); }
.log .warnline { color: var(--warn); }
.log .badline { color: var(--bad); }
.log .okline { color: var(--good); }

.primer-list { margin: 0; padding-left: 20px; color: var(--ink-dim); font-size: 13.5px; }
.primer-list li { margin-bottom: 9px; }
.primer-list b { color: var(--ink); font-weight: 620; }

@media (max-width: 980px) {
  .work-grid, .result-grid { grid-template-columns: 1fr; }
  .budget-grid { grid-template-columns: 1fr 1fr; }
}

/* ---------------------------------------------------------------- phone
   The desktop layout leans on absolute positioning in panel heads and on a
   header that spreads across the width. Both overflow a handset, and a page
   that scrolls sideways feels broken before you have tried anything. */
@media (max-width: 720px) {
  /* `overflow-x` on BODY is why the sticky Forge button below has never once
     pinned on a phone. Any overflow other than `visible` on body makes it a
     scroll container, and a sticky child cannot pin against an ancestor
     scroll container that does not itself scroll. Measured before the fix: the
     button tracked scroll one-for-one, 1832 -> 1532 -> 1232 -> 932 -> 632 at
     300px steps, when it should have pinned at 752.

     Putting it on `html` alone still makes sideways scrolling impossible —
     documentElement.scrollWidth stays equal to clientWidth — and lets sticky
     work. The rule sat here for months asserting an accommodation it was
     silently cancelling four hundred lines further down. */
  html { max-width: 100%; overflow-x: hidden; }
  body { max-width: 100%; }

  /* The thing you came to do goes first.
     On a wide screen the link budget sits above the dropzone and reads as the
     premise: state your link, then everything aims at it. Stacked on a handset
     that premise costs 1.22 screens of scrolling before "Load something" is even
     visible — measured — so the first thing a new operator sees is a radio
     configuration panel and not a way in. `main` is a flex column, so one
     `order` puts the action above the premise without touching the desktop
     layout. Whichever of the two is showing wins the top slot. */
  #dropPanel, #workPanel { order: -1; }

  /* Capability badges: one summary pill until asked. The button only exists on
     a phone and only when every check passed — reportCapabilities refuses to
     build it otherwise, so a failure can never be hidden behind a tap. */
  .caps-summary { display: inline-flex; }
  .caps .pill { display: none; }
  .caps.open .pill { display: inline-flex; }

  .topbar {
    flex-direction: column; align-items: stretch; gap: 14px;
    padding: 16px 14px 14px;
  }
  .brand { align-items: flex-start; }
  .brand h1 { font-size: 21px; }
  .brand p { font-size: 12.5px; }
  .anvil { width: 28px; height: 28px; }
  .topbar-right { flex-direction: column; align-items: stretch; gap: 10px; }
  .topbar-right .segmented { width: 100%; }
  .caps { justify-content: flex-start; }
  .pill {
    font-size: 10px; padding: 5px 8px; white-space: normal;
    max-width: 100%; overflow-wrap: anywhere;
  }

  main { padding: 14px 12px 60px; gap: 14px; }
  .panel { padding: 14px; border-radius: 10px; }

  /* Panel-head controls stop floating and take their own row. */
  .panel-head .ghost, .panel-head .segmented {
    position: static; width: 100%; margin-top: 10px;
  }
  .panel-head p { font-size: 13px; }

  .budget-grid, .two-up, .compare, .result-grid { grid-template-columns: 1fr; }
  .budget-readout strong { font-size: 22px; }

  .presetbar { gap: 6px; }
  .presetbar select { min-width: 0; width: 100%; }
  .presetbar button { flex: 1 1 auto; }
  .presetbar .spacer { display: none; }

  .dropzone { padding: 30px 14px; }
  .stage { max-height: none; }
  .stage-tools { gap: 6px; }
  .chips { width: 100%; }

  /* Fingers are not mouse pointers. Bigger targets everywhere it matters. */
  .crop-handle { width: 22px; height: 22px; border-radius: 5px; }
  .crop-nw { left: -11px; top: -11px; }
  .crop-ne { right: -11px; top: -11px; }
  .crop-sw { left: -11px; bottom: -11px; }
  .crop-se { right: -11px; bottom: -11px; }
  .crop-n  { top: -11px; }
  .crop-s  { bottom: -11px; }
  .crop-w  { left: -11px; }
  .crop-e  { right: -11px; }

  input[type=number], input[type=text], select, textarea {
    /* Under 16px, iOS zooms the whole page in when a field is focused and
       never zooms back out. */
    font-size: 16px; padding: 11px 12px;
  }
  input[type=range] { height: 32px; }
  button { padding: 11px 14px; min-height: 44px; }
  .small { padding: 9px 12px; min-height: 40px; }
  .check { padding: 4px 0; }
  .check input { width: 20px; height: 20px; }

  .deliver { flex-direction: column; }
  .deliver button { width: 100%; }
  .rx-actions { flex-direction: column; }
  .rx-actions .forge { width: 100%; }

  #statsList, #rxStats { grid-template-columns: 1fr auto; gap: 6px 10px; }
  #statsList dt, #rxStats dt { font-size: 11px; }
  #statsList dd, #rxStats dd { font-size: 12px; overflow-wrap: anywhere; }

  #armorText, #rxText { height: 130px; font-size: 10.5px; }
  .log { max-height: 130px; font-size: 11px; }
  .target-readout { font-size: 11.5px; }
  .primer-list { font-size: 12.5px; padding-left: 16px; }
  .contact-sheet img { max-height: 220px; object-fit: contain; }
  .blockmap i { width: 16px; height: 16px; }

  /* The forge button is the thing you came to press; keep it reachable
     without scrolling back up past a column of settings. */
  .controls-col .forge {
    position: sticky; bottom: 10px; z-index: 5;
    box-shadow: 0 8px 26px -6px rgba(0, 0, 0, 0.85), 0 6px 22px -8px #ff6a1399;
  }
}

/* ---------------------------------------------------------------- session */

.sessiontable { display: flex; flex-direction: column; gap: 2px; margin-bottom: 12px; }
.sessiontable .row {
  display: grid; grid-template-columns: 128px 1fr auto auto;
  gap: 12px; align-items: baseline;
  padding: 6px 8px; border-radius: 6px;
  font: 12px/1.4 var(--mono); color: var(--ink-dim);
}
.sessiontable .row:nth-child(odd) { background: #0f141d; }
.sessiontable .row b { color: var(--ink); font-weight: 600; overflow-wrap: anywhere; }
.sessiontable .row .win { color: var(--good); }
.sessiontable .empty { color: var(--ink-faint); font-size: 12.5px; padding: 4px 8px; }

#armorResend, #rxResendLine { font: 12px var(--mono); }
.armor-head .field.inline { flex: 0 1 auto; }
#rxHeld { margin-top: 10px; }

/* The receive verdict has four states and three of them are not "fine".
   Colour carries the difference at a glance; the sentence carries the detail. */
#rxVerdict.good { color: var(--good); }
#rxVerdict.bad  { color: var(--bad); font-weight: 600; }
#dataVerdict.bad { color: var(--bad); font-weight: 600; }

/* The ATAK panel: four short fields side by side, because a marker type and a
   callsign are read together, not one after the other. */
.atak-out { margin-top: 12px; display: flex; flex-direction: column; gap: 10px; }
.atak-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
@media (max-width: 620px) { .atak-grid { grid-template-columns: 1fr; } }

/* The workings. Shown outright on a desktop, where there is room and reading
   them costs nothing; folded on a phone behind a count of what is hidden, so
   the fold is honest about its own size. */
.stats-toggle { display: none; align-self: flex-start; }
@media (max-width: 720px) {
  .stats-toggle { display: inline-flex; }
  #statsMore { display: none; }
  #statsMore.open { display: grid; }
}
