/* One stylesheet, no framework. Mobile first, because the link a photographer
   pastes into a forum thread is opened on a phone even though the stacking is
   done at a desk.

   The page is dark by default and stays dark in a light system theme. This is
   the one site in the fleet where that is not a style preference: the visitor is
   looking at a night sky at one in the morning, often on the laptop that is
   plugged into the camera, and a white page in that room is a flashbulb. */

:root {
  color-scheme: dark;
  --ink: #e8eaf0;
  --ink-soft: #9aa3b4;
  --paper: #0d1015;
  --card: #151a22;
  --line: #262d39;
  --accent: #d9a441;
  --accent-ink: #17120a;
  --warn: #e2a04a;
  --bad: #e0736b;
  --radius: 10px;
  --measure: 36rem;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 16px/1.65 ui-serif, Georgia, "Times New Roman", serif;
  -webkit-text-size-adjust: 100%;
}

.wrap { max-width: 48rem; margin: 0 auto; padding: 1.5rem 1.15rem 4rem; }

h1, h2, h3 { line-height: 1.25; font-weight: 600; letter-spacing: -0.01em; }
h1 { font-size: 1.8rem; margin: 0 0 0.6rem; }
h2 { font-size: 1.28rem; margin: 2.2rem 0 0.6rem; }
h3 { font-size: 1.06rem; margin: 1.4rem 0 0.4rem; }
p, li { max-width: var(--measure); }
p { margin: 0 0 0.9rem; }

a { color: var(--accent); text-underline-offset: 0.15em; }
a:focus-visible, button:focus-visible, input:focus-visible, canvas:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* EVERY NAVIGATION LINK IS A 44px TARGET. Inline text in a flex row is as tall
   as its line box, about 24px, and a 24px target is a mis-tap on a phone held
   one-handed in the dark. Padding rather than a fixed height, so the text sits
   where it looks like it should. */
header.site-header { display: flex; align-items: center; gap: 0.25rem 0.9rem; flex-wrap: wrap; margin-bottom: 1.4rem; }
header.site-header a.brand {
  font-weight: 600; text-decoration: none; color: var(--ink); font-size: 1.05rem;
  display: inline-flex; align-items: center; gap: 0.5rem; min-height: 44px;
}
header.site-header nav { display: flex; gap: 0.9rem; font-size: 0.9rem; font-family: ui-sans-serif, system-ui, sans-serif; flex-wrap: wrap; }
header.site-header nav a { display: inline-flex; align-items: center; justify-content: center; min-height: 44px; min-width: 44px; }

.lede { font-size: 1.06rem; color: var(--ink-soft); }

/* --- the tool, which has to dominate ------------------------------------ */

.tool {
  margin: 1.75rem 0 2.5rem;
  padding: 1.4rem 1.1rem 1.6rem;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 14px;
}
@media (min-width: 52rem) { .tool { padding: 1.9rem 1.9rem 2.1rem; } }

/* THE LABEL IS THE TARGET and it wraps the input, so the whole zone is
   tappable by construction. Drag is layered on by script; a touch device has no
   drag at all. */
.file-drop {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.55rem;
  min-block-size: 11rem;
  padding: 2.1rem 1.1rem;
  border: 2px dashed var(--line);
  border-radius: 12px;
  text-align: center;
  cursor: pointer;
  background: #10141b;
  transition: border-color 120ms ease, background-color 120ms ease;
}
.file-drop:hover { border-color: var(--accent); }
.file-drop input[type="file"] {
  position: absolute;
  inline-size: 1px; block-size: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.file-drop:focus-within { border-color: var(--accent); outline: 3px solid var(--accent); outline-offset: 3px; }
.file-drop-mark { color: var(--accent); }
.file-drop-mark svg { inline-size: 2.4rem; block-size: 2.4rem; display: block; }
.file-drop-label { font: 600 1.15rem/1.3 ui-sans-serif, system-ui, sans-serif; color: var(--ink); }
.file-drop-hint { color: var(--ink-soft); font-size: 0.9rem; max-width: 27rem; }
.file-drop.is-dragging { border-color: var(--accent); border-style: solid; background: var(--card); }

.folder-row { margin: 0.75rem 0 0; text-align: center; font: 0.9rem ui-sans-serif, system-ui, sans-serif; color: var(--ink-soft); }
.folder-row label { display: inline-flex; align-items: center; min-height: 44px; color: var(--accent); cursor: pointer; text-decoration: underline; }
.folder-row input { position: absolute; inline-size: 1px; block-size: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); }

@media (prefers-reduced-motion: reduce) { .file-drop { transition: none; } }

/* --- the panel ---------------------------------------------------------- */

.panel { margin-top: 1.4rem; }
.tool .panel:not([hidden]) { border-top: 1px solid var(--line); padding-top: 1.2rem; }

.progress {
  height: 6px; border-radius: 3px; background: var(--line); overflow: hidden;
  margin: 0.5rem 0 1rem;
  font: 0.8rem/6px ui-sans-serif, system-ui, sans-serif; color: var(--ink-soft);
}
.progress::after {
  content: ""; display: block; height: 100%;
  width: calc(var(--fraction, 0) * 100%);
  background: var(--accent);
  transition: width 150ms linear;
}
@media (prefers-reduced-motion: reduce) {
  .progress { background: none; height: auto; line-height: 1.4; }
  .progress::after { display: none; }
}

/* The preview's box is reserved before the first frame exists. That is the CLS
   budget in the build spec: the picture appears INTO a space that was already
   there, so nothing below it moves. */
#preview-figure { margin: 0 0 1rem; }
#preview-figure canvas {
  display: block; width: 100%; height: auto; aspect-ratio: 3 / 2;
  background: #05070a; border: 1px solid var(--line); border-radius: 8px;
  object-fit: contain;
}
#preview-figure figcaption { font: 0.85rem ui-sans-serif, system-ui, sans-serif; color: var(--ink-soft); margin-top: 0.4rem; }

dl.facts { display: grid; grid-template-columns: auto 1fr; gap: 0.3rem 0.9rem; margin: 0.4rem 0 1rem; font: 0.92rem ui-sans-serif, system-ui, sans-serif; }
dl.facts dt { color: var(--ink-soft); }
dl.facts dd { margin: 0; font-variant-numeric: tabular-nums; }

/* The computed default, shown WITH its arithmetic. The whole argument against
   the slider every other tool ships is that this number is derivable, so the
   page has to show the derivation rather than assert the answer. */
.computed {
  margin: 0.8rem 0; padding: 0.85rem 1rem;
  border: 1px solid var(--line); border-left: 3px solid var(--accent);
  border-radius: 0 var(--radius) var(--radius) 0;
  background: #10141b;
  font-size: 0.95rem;
}

.note { margin: 0.6rem 0; padding-left: 0.85rem; border-left: 3px solid var(--line); font-size: 0.95rem; color: var(--ink-soft); }
.note-warning { border-left-color: var(--warn); }
.note-refusal { border-left-color: var(--bad); }

#findings { margin: 0.8rem 0 1rem; }
#findings strong { color: var(--ink); }

.primary {
  display: inline-block; margin-top: 1rem; padding: 0.7rem 1.1rem;
  border: 0; border-radius: var(--radius);
  background: var(--accent); color: var(--accent-ink);
  font: 600 1rem/1.2 ui-sans-serif, system-ui, sans-serif;
  text-decoration: none; cursor: pointer; min-height: 44px;
}

button.ghost {
  margin: 1rem 0.5rem 0 0; padding: 0.5rem 0.9rem;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: none; color: var(--ink-soft);
  font: 0.92rem ui-sans-serif, system-ui, sans-serif; cursor: pointer; min-height: 44px;
}

/* THE REFUSAL LOOKS AS CONSIDERED AS THE SUCCESS. "This needs a desktop, and
   here is the memory number" is the screen that earns trust, so it is set in
   the reading serif with the accent rule every other considered aside uses —
   not in a red error box. */
.honest {
  margin-top: 1.1rem; padding: 1.1rem 1.2rem;
  border: 1px solid var(--line); border-left: 4px solid var(--accent);
  background: #10141b; border-radius: 0 var(--radius) var(--radius) 0;
}
.honest h3 { margin-top: 0; font-size: 1.1rem; }
.quiet { color: var(--ink-soft); font-size: 0.92rem; }
ul.result-notes { padding-left: 1.1rem; }
ul.result-notes li { margin-bottom: 0.4rem; }

/* --- the side by side --------------------------------------------------- */

.compare { margin-top: 1.4rem; }
.compare-pair { display: grid; gap: 0.9rem; grid-template-columns: 1fr; }
@media (min-width: 40rem) { .compare-pair { grid-template-columns: 1fr 1fr; } }
.compare-pair figure { margin: 0; }
.compare-pair canvas {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--line); border-radius: 8px; background: #05070a;
}
.compare-pair figcaption { font: 0.85rem ui-sans-serif, system-ui, sans-serif; color: var(--ink-soft); margin-top: 0.35rem; }

/* --- reading pages ------------------------------------------------------ */

/* THE TABLE SCROLLS, THE PAGE DOES NOT. The five-column comparison on
   /star-trails-on-mac/ needs 507px and an iPhone SE has 320: measured, it made
   the whole document scroll sideways by 206px, which is the defect the
   catalogue's `data-table` invariant exists to prevent. A scroller of its own
   keeps the table readable at full width and leaves the document alone. */
.table-scroll {
  overflow-x: auto;
  margin: 1rem 0;
  -webkit-overflow-scrolling: touch;
  /* SCROLLING SHADOWS. A table clipped at the right edge with no affordance
     looks broken rather than scrollable — opened on the iPhone 17 simulator,
     the comparison table simply appeared to be missing its last column. These
     four layers are the standard pure-CSS answer: the white "cover" layers are
     `background-attachment: local` so they travel with the content, the shadow
     layers are `scroll` so they stay pinned, and a shadow is therefore visible
     only on the side that has more table behind it. No script, and it cannot
     get out of step with the actual scroll position. */
  background:
    linear-gradient(to right, var(--paper) 30%, rgb(13 16 21 / 0%)) left center / 2.5rem 100% no-repeat local,
    linear-gradient(to left, var(--paper) 30%, rgb(13 16 21 / 0%)) right center / 2.5rem 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%, rgb(0 0 0 / 55%), rgb(0 0 0 / 0%)) left center / 1.1rem 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%, rgb(0 0 0 / 55%), rgb(0 0 0 / 0%)) right center / 1.1rem 100% no-repeat scroll;
}
.table-scroll table.data { margin: 0; min-width: 100%; }
table.data { width: 100%; border-collapse: collapse; font: 0.93rem ui-sans-serif, system-ui, sans-serif; margin: 1rem 0; }
table.data th, table.data td { text-align: left; padding: 0.5rem 0.45rem; border-bottom: 1px solid var(--line); vertical-align: top; }
table.data thead th { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ink-soft); }
table.data td.number { text-align: right; font-variant-numeric: tabular-nums; }

dl.specs-list dt { font-weight: 600; margin-top: 1rem; }
dl.specs-list dd { margin: 0.2rem 0 0; color: var(--ink-soft); max-width: var(--measure); }

figure.evidence { margin: 1.2rem 0; }
figure.evidence img { width: 100%; height: auto; border: 1px solid var(--line); border-radius: 8px; display: block; }
figure.evidence figcaption { font: 0.85rem ui-sans-serif, system-ui, sans-serif; color: var(--ink-soft); margin-top: 0.4rem; }

footer {
  margin-top: 3rem; padding-top: 1.2rem; border-top: 1px solid var(--line);
  font: 0.88rem ui-sans-serif, system-ui, sans-serif; color: var(--ink-soft);
}
footer nav { display: flex; gap: 0.25rem 0.9rem; flex-wrap: wrap; margin-bottom: 0.6rem; }
footer nav a { display: inline-flex; align-items: center; justify-content: center; min-height: 44px; min-width: 44px; }

/* A LINK INSIDE RUNNING PROSE IS A 19px TARGET, and on a phone at 1am that is a
   mis-tap. Vertical padding on an inline element does not change the line box,
   so this enlarges the hit area to 44px without moving a single word. Measured
   at 320px across five routes before and after. */
main p a, main dd a, main li a, main figcaption a { padding-block: 0.8rem; }
footer p { color: var(--ink); max-width: var(--measure); }
