/* ==========================================================================
   Matrix QR — visual system

   Dark first. The palette comes from the two things the product is actually
   made of: a printed QR code (pure ink on pure paper) and a terminal. Black
   backgrounds, one green that behaves like a live signal rather than
   decoration, and a single family of translucent surfaces.

   The green is used only where something is live or actionable. Painting the
   whole interface in it is the mistake this restraint exists to avoid: if
   everything glows, nothing reads as important.

   Everything is written with logical properties (inline-start/end), so the
   Persian and Arabic layouts mirror without a second stylesheet.
   ========================================================================== */

:root {
  /* Surfaces, darkest to lightest. */
  --paper:      #080c0b;
  --paper-2:    #0f1614;
  --paper-3:    #16201d;

  --ink:        #e6f1ec;
  --ink-2:      #a9bdb5;
  --slate:      #6f8781;
  --line:       #1d2b27;

  /* The signal. --signal is the live green; --signal-ink is what text and
     borders use, kept a shade calmer so long runs of it do not vibrate. */
  --signal:     #2fe39b;
  --signal-ink: #55f0b3;
  --signal-bg:  rgba(47, 227, 155, .10);
  --signal-dim: rgba(47, 227, 155, .35);
  --glow:       0 0 0 1px rgba(47, 227, 155, .18), 0 0 24px -6px rgba(47, 227, 155, .35);

  --warn:       #f0b866;
  --warn-bg:    rgba(240, 184, 102, .12);
  --danger:     #ff7a70;
  --danger-bg:  rgba(255, 122, 112, .12);

  --radius:     14px;
  --radius-sm:  9px;
  --shadow:     0 1px 2px rgba(0, 0, 0, .5), 0 14px 40px -20px rgba(0, 0, 0, .9);
  --measure:    68ch;

  /* Translucent surface + blur, used only where there is something behind it. */
  --glass:      rgba(15, 22, 20, .72);
  --glass-line: rgba(230, 241, 236, .07);

  --font-sans: "IBM Plex Sans", "Vazirmatn", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;
}

/* The light theme is a real option, not an afterthought: same structure, same
   restraint, ink on paper instead of signal on black. */
[data-theme="light"] {
  --paper:      #ffffff;
  --paper-2:    #f5f8f7;
  --paper-3:    #eef3f1;
  --ink:        #0a0f0d;
  --ink-2:      #35454a;
  --slate:      #5c6b70;
  --line:       #e2e7e6;
  --signal:     #00a37f;
  --signal-ink: #00795e;
  --signal-bg:  rgba(0, 163, 127, .09);
  --signal-dim: rgba(0, 163, 127, .3);
  --glow:       none;
  --warn:       #a4501c;
  --warn-bg:    #fdf1e7;
  --danger:     #b3261e;
  --danger-bg:  #fdecea;
  --shadow:     0 1px 2px rgba(11, 17, 20, .06), 0 8px 24px -12px rgba(11, 17, 20, .18);
  --glass:      rgba(255, 255, 255, .78);
  --glass-line: rgba(11, 17, 20, .06);
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.6;
  font-feature-settings: "kern", "liga";
  -webkit-font-smoothing: antialiased;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

[dir="rtl"] body { font-family: "Vazirmatn", var(--font-sans); }

h1, h2, h3 { line-height: 1.18; margin: 0 0 .5em; font-weight: 600; letter-spacing: -.015em; }
h1 { font-size: clamp(1.85rem, 1.3rem + 2.4vw, 3.1rem); }
h2 { font-size: clamp(1.3rem, 1.1rem + .9vw, 1.9rem); }
h3 { font-size: 1.08rem; font-weight: 600; }
p  { margin: 0 0 1em; max-width: var(--measure); }

a { color: var(--signal-ink); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--ink); }

:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 2px;
  border-radius: 4px;
}

code, .mono, kbd { font-family: var(--font-mono); font-size: .92em; }

.wrap { width: 100%; max-width: 1080px; margin-inline: auto; padding-inline: 20px; }
.narrow { max-width: 700px; }

/* ---------------------------------------------------------------- header */
.site-head {
  border-block-end: 1px solid var(--line);
  background: var(--paper);
  position: sticky;
  top: 0;
  z-index: 40;
}
.head-row {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 62px;
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
  letter-spacing: -.02em;
  margin-inline-end: auto;
}
.brand-mark { width: 26px; height: 26px; display: block; flex: none; }

.nav { display: flex; align-items: center; gap: 4px; }
.nav a, .nav button {
  font: inherit;
  font-size: .93rem;
  color: var(--ink-2);
  text-decoration: none;
  padding: 7px 11px;
  border-radius: var(--radius-sm);
  border: 0;
  background: none;
  cursor: pointer;
  white-space: nowrap;
}
.nav a:hover, .nav button:hover { background: var(--paper-2); color: var(--ink); }
.nav a.current { color: var(--ink); font-weight: 500; }

.nav-toggle { display: none; }

@media (max-width: 780px) {
  .nav-toggle { display: inline-flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; border: 1px solid var(--line); border-radius: var(--radius-sm);
    background: var(--paper); color: var(--ink); cursor: pointer; }
  .nav {
    display: none;
    position: absolute;
    inset-inline: 12px;
    top: 60px;
    flex-direction: column;
    align-items: stretch;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 8px;
    box-shadow: var(--shadow);
  }
  .nav.open { display: flex; }
  .nav a, .nav button { text-align: start; padding: 11px 12px; }
}

/* ------------------------------------------------------------------ main */
main { flex: 1 0 auto; padding-block: 40px 64px; }
.section + .section { margin-block-start: 56px; }

/* ------------------------------------------------------------------ hero */
.hero {
  display: grid;
  grid-template-columns: 1.05fr .95fr;
  gap: 48px;
  align-items: center;
}
.hero-copy p { color: var(--ink-2); font-size: 1.08rem; max-width: 48ch; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-block-start: 26px; }

/* The hero is the product's own output: a QR card exactly like the one it
   generates. Nothing explains the product faster than showing it. */
.qr-card {
  /* Always white: this is a preview of a printed card, not a UI surface. */
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 28px;
  display: grid;
  justify-items: center;
  gap: 14px;
  max-width: 340px;
  margin-inline: auto;
}
.qr-card svg, .qr-card img { width: 100%; height: auto; display: block; border-radius: 4px; }
.qr-card .qr-id { font-family: var(--font-mono); font-size: 1.25rem; color: #0b1114; letter-spacing: .04em; }
.qr-card .qr-host { font-size: .82rem; color: #5c6b70; }

@media (max-width: 860px) {
  .hero { grid-template-columns: 1fr; gap: 32px; }
  .hero-card { order: -1; }
  .qr-card { max-width: 260px; padding: 20px; }
}

/* --------------------------------------------------------------- buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font: inherit;
  font-weight: 500;
  font-size: .96rem;
  padding: 11px 18px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink);
  text-decoration: none;
  cursor: pointer;
  transition: background .12s ease, border-color .12s ease;
}
.btn:hover { background: var(--paper-2); color: var(--ink); }
.btn-primary {
  background: var(--signal);
  border-color: var(--signal);
}
.btn-primary:hover { filter: brightness(1.08); }
.btn-primary { color: #04120d; }
.btn-primary:hover { background: var(--signal-ink); color: #04120d; }
[data-theme="light"] .btn-primary { color: #fff; }
[data-theme="light"] .btn-primary:hover { background: var(--ink); border-color: var(--ink); color: #fff; }
.btn-danger { color: var(--danger); border-color: var(--line); }
.btn-danger:hover { background: var(--danger-bg); }
.btn-block { width: 100%; }
.btn-sm { padding: 7px 12px; font-size: .88rem; }
.btn[disabled], .btn[aria-disabled="true"] { opacity: .5; pointer-events: none; }

/* ----------------------------------------------------------------- cards */
.card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 22px;
}
.card + .card { margin-block-start: 16px; }
.card-quiet { background: var(--paper-2); }

.grid { display: grid; gap: 16px; }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 780px) {
  .grid-3, .grid-2 { grid-template-columns: 1fr; }
}

/* The three steps genuinely are a sequence, so they are numbered. */
.steps { counter-reset: step; display: grid; gap: 18px; grid-template-columns: repeat(3, 1fr); }
.step { counter-increment: step; padding-block-start: 14px; border-block-start: 2px solid var(--ink); }
.step::before {
  content: counter(step);
  font-family: var(--font-mono);
  font-size: .8rem;
  color: var(--slate);
  display: block;
  margin-block-end: 6px;
}
.step p { margin: 0; color: var(--ink-2); font-size: .96rem; }
@media (max-width: 780px) { .steps { grid-template-columns: 1fr; } }

/* ----------------------------------------------------------------- stats */
.stat-grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); }
.stat {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 14px 16px;
  background: var(--paper);
}
.stat .n { font-size: 1.6rem; font-weight: 600; font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.stat .k { font-size: .82rem; color: var(--slate); }

/* ----------------------------------------------------------------- forms */
label { display: block; font-size: .9rem; font-weight: 500; margin-block-end: 6px; }
.hint { font-size: .84rem; color: var(--slate); margin-block-start: 5px; }
.field + .field { margin-block-start: 18px; }

input[type="text"], input[type="email"], input[type="password"],
input[type="number"], input[type="search"], select, textarea {
  width: 100%;
  font: inherit;
  font-size: .97rem;
  padding: 11px 13px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--paper);
  color: var(--ink);
}
textarea { min-height: 84px; resize: vertical; }
input:focus, select:focus, textarea:focus { border-color: var(--signal); outline: none;
  box-shadow: 0 0 0 3px var(--signal-bg); }

.check { display: flex; align-items: flex-start; gap: 10px; font-weight: 400; }
.check input { margin-block-start: 4px; width: 17px; height: 17px; accent-color: var(--signal-ink); flex: none; }

/* -------------------------------------------------------------- dropzone */
.dropzone {
  border: 2px dashed var(--line);
  border-radius: var(--radius);
  padding: 40px 20px;
  text-align: center;
  cursor: pointer;
  background: var(--paper-2);
  transition: border-color .15s ease, background .15s ease;
}
.dropzone:hover, .dropzone.hot { border-color: var(--signal); background: var(--signal-bg); }
.dropzone strong { display: block; font-size: 1.05rem; }
.dropzone span { color: var(--slate); font-size: .9rem; }
.dropzone input { display: none; }
.dz-preview { max-height: 260px; border-radius: var(--radius-sm); margin-block-end: 12px; }

/* --------------------------------------------------------------- notices */
.notice {
  border: 1px solid var(--line);
  border-inline-start: 3px solid var(--signal);
  background: var(--signal-bg);
  color: var(--ink);
  padding: 12px 15px;
  border-radius: var(--radius-sm);
  margin-block-end: 20px;
  font-size: .94rem;
}
.notice-error { border-inline-start-color: var(--danger); background: var(--danger-bg); }
.notice-warn  { border-inline-start-color: var(--warn); background: var(--warn-bg); }

/* --------------------------------------------------------- link/copy row */
.copyrow {
  display: flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 8px 8px 8px 13px;
  background: var(--paper-2);
}
.copyrow .val {
  flex: 1;
  min-width: 0;
  font-family: var(--font-mono);
  font-size: .85rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  direction: ltr;
  text-align: start;
}
.copyrow .btn { flex: none; }

/* ------------------------------------------------------------ photo page */
.photo-stage {
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 10px;
  display: grid;
  place-items: center;
  margin-block-end: 18px;
}
.photo-stage img {
  max-width: 100%;
  max-height: 72dvh;
  height: auto;
  border-radius: var(--radius-sm);
  display: block;
}
/* Two doors, equal weight — the whole idea of the product in one row. */
.doors { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
@media (max-width: 560px) { .doors { grid-template-columns: 1fr; } }

.meta-row {
  display: flex; flex-wrap: wrap; gap: 6px 16px;
  color: var(--slate); font-size: .87rem; margin-block: 14px;
}
.meta-row .id { font-family: var(--font-mono); color: var(--ink-2); }

/* --------------------------------------------------------------- gallery */
.gallery { display: grid; gap: 16px; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); }
.tile {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--paper);
  display: flex;
  flex-direction: column;
}
.tile-img { aspect-ratio: 4 / 3; background: var(--paper-2); overflow: hidden; display: block; }
.tile-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tile-body { padding: 12px 13px; display: grid; gap: 7px; }
.tile-id { font-family: var(--font-mono); font-size: .9rem; }
.tile-meta { font-size: .8rem; color: var(--slate); display: flex; gap: 12px; flex-wrap: wrap; }
.tile-actions { display: flex; gap: 6px; padding: 0 13px 13px; }

/* ----------------------------------------------------------------- table */
.table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); }
table { width: 100%; border-collapse: collapse; font-size: .92rem; }
th, td { padding: 11px 14px; text-align: start; border-block-end: 1px solid var(--line); white-space: nowrap; }
th { font-weight: 600; font-size: .8rem; color: var(--slate); background: var(--paper-2); }
tbody tr:last-child td { border-block-end: 0; }
tbody tr:hover { background: var(--paper-2); }

/* ----------------------------------------------------------------- chips */
.chip {
  display: inline-block;
  font-size: .76rem;
  padding: 2px 9px;
  border-radius: 999px;
  border: 1px solid var(--line);
  color: var(--slate);
  background: var(--paper);
}
.chip-ok { color: var(--signal-ink); border-color: var(--signal); background: var(--signal-bg); }
.chip-warn { color: var(--warn); border-color: var(--warn); background: var(--warn-bg); }
.chip-bad { color: var(--danger); border-color: var(--danger); background: var(--danger-bg); }

/* ------------------------------------------------------------ empty/gone */
.empty { text-align: center; padding: 56px 20px; }
.empty h2 { margin-block-end: 8px; }
.empty p { margin-inline: auto; color: var(--ink-2); }

/* ---------------------------------------------------------------- pager */
.pager { display: flex; gap: 8px; align-items: center; justify-content: center; margin-block-start: 26px; }
.pager .n { font-size: .88rem; color: var(--slate); }

/* --------------------------------------------------------------- sparks */
.spark { display: flex; align-items: flex-end; gap: 3px; height: 54px; }
.spark i {
  flex: 1;
  background: var(--signal);
  border-radius: 2px 2px 0 0;
  min-height: 2px;
  display: block;
  opacity: .85;
}

/* ---------------------------------------------------------------- admin */
.admin-bar {
  display: flex; gap: 4px; flex-wrap: wrap;
  border-block-end: 1px solid var(--line);
  padding-block-end: 12px; margin-block-end: 26px;
}
.admin-bar a {
  font-size: .92rem; padding: 7px 12px; border-radius: var(--radius-sm);
  color: var(--ink-2); text-decoration: none;
}
.admin-bar a:hover { background: var(--paper-2); color: var(--ink); }
.admin-bar a.current { background: var(--ink); color: var(--paper); }

.toolbar { display: flex; gap: 8px; flex-wrap: wrap; margin-block-end: 18px; }
.toolbar input[type="search"], .toolbar select { max-width: 320px; }

/* ---------------------------------------------------------------- footer */
.site-foot {
  border-block-start: 1px solid var(--line);
  padding-block: 26px;
  font-size: .87rem;
  color: var(--slate);
}
.foot-row { display: flex; flex-wrap: wrap; gap: 8px 18px; align-items: center; }
.foot-row a { color: var(--slate); text-decoration: none; }
.foot-row a:hover { color: var(--ink); text-decoration: underline; }
.foot-row .sep { margin-inline-start: auto; }

.lang-switch { display: inline-flex; gap: 2px; }
.lang-switch a { padding: 4px 8px; border-radius: 6px; font-size: .85rem; }
.lang-switch a.current { background: var(--paper-2); color: var(--ink); }

/* ------------------------------------------------------------ utilities */
.stack > * + * { margin-block-start: 14px; }
.row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.muted { color: var(--slate); }
.tabular { font-variant-numeric: tabular-nums; }
.center { text-align: center; }
.mt-0 { margin-block-start: 0; }
.hidden { display: none !important; }
.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;
}
.skip-link {
  position: absolute; inset-inline-start: 12px; top: -60px;
  background: var(--ink); color: var(--paper); padding: 10px 14px;
  border-radius: var(--radius-sm); z-index: 100; transition: top .15s ease;
}
.skip-link:focus { top: 12px; }

/* The one deliberate motion in the product: the hero card settles into place
   on first paint, the way a printed card is set down on a table. */
@keyframes settle {
  from { opacity: 0; transform: translateY(10px) rotate(-.6deg); }
  to   { opacity: 1; transform: none; }
}
.hero-card .qr-card { animation: settle .5s cubic-bezier(.2, .7, .3, 1) both; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

@media print {
  .site-head, .site-foot, .hero-actions, .doors, .btn { display: none !important; }
  body { background: #fff; color: #000; }
}


/* ------------------------------------------------------------------ video */
.photo-stage video {
  max-width: 100%;
  max-height: 72dvh;
  height: auto;
  border-radius: var(--radius-sm);
  display: block;
  background: #000;
}
/* A duration badge tells you it is a video before the poster loads. */
.tile-img { position: relative; }
.tile-badge {
  position: absolute;
  inset-block-end: 8px;
  inset-inline-end: 8px;
  background: rgba(11, 17, 20, .82);
  color: #fff;
  font-size: .74rem;
  font-variant-numeric: tabular-nums;
  padding: 2px 7px;
  border-radius: 5px;
  pointer-events: none;
}
.tile-play {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  pointer-events: none;
}
.tile-play svg { filter: drop-shadow(0 2px 6px rgba(0, 0, 0, .55)); }

/* --------------------------------------------------------- separate links
   Three different things, three visually distinct blocks. Merging them into
   one "share" control is exactly the confusion this layout prevents. */
.links { display: grid; gap: 12px; }
.link-block {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px;
  background: var(--paper);
}
.link-head {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-block-end: 8px;
}
.link-kind { font-weight: 500; font-size: .94rem; }
.link-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-block-start: 10px; }
.link-actions .btn { flex: 1 1 auto; min-width: 92px; }

/* ------------------------------------------------------------------ charts
   Drawn as inline SVG so they render on first paint and print correctly. */
.chart { width: 100%; height: 160px; display: block; overflow: visible; }
.bars { display: grid; gap: 10px; }
.bar-row { display: grid; grid-template-columns: 7rem 1fr auto; gap: 10px; align-items: center; }
.bar-track {
  height: 9px; background: var(--paper-2); border-radius: 999px; overflow: hidden;
  border: 1px solid var(--line);
}
.bar-fill { display: block; height: 100%; background: var(--signal); border-radius: 999px; }
.bar-label { font-size: .88rem; color: var(--ink-2); }
.bar-value { font-size: .82rem; color: var(--slate); white-space: nowrap; }
@media (max-width: 560px) {
  .bar-row { grid-template-columns: 5.5rem 1fr; }
  .bar-value { grid-column: 2; text-align: end; }
}

/* ------------------------------------------------------- library controls */
.filter-tabs { display: flex; gap: 4px; flex-wrap: wrap; margin-block-start: 18px; }
.filter-tabs a {
  padding: 7px 14px; border-radius: 999px; font-size: .9rem;
  color: var(--ink-2); text-decoration: none; border: 1px solid var(--line);
}
.filter-tabs a:hover { background: var(--paper-2); color: var(--ink); }
.filter-tabs a.current { background: var(--ink); border-color: var(--ink); color: var(--paper); }

/* Appears only once something is selected, so the page stays quiet by default. */
.bulkbar {
  position: sticky; top: 70px; z-index: 20;
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 10px 12px; margin-block-end: 14px;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--paper); box-shadow: var(--shadow);
}
.bulkbar-count { font-size: .88rem; font-weight: 500; margin-inline-end: auto; }

.tile { position: relative; }
.tile-pick {
  position: absolute; inset-block-start: 8px; inset-inline-start: 8px; z-index: 2;
  background: rgba(8, 12, 11, .82); border-radius: 6px; padding: 3px;
  line-height: 0; box-shadow: 0 1px 3px rgba(11, 17, 20, .25);
}
[data-theme="light"] .tile-pick { background: rgba(255, 255, 255, .92); }
.tile-pick input { width: 18px; height: 18px; accent-color: var(--signal-ink); margin: 0; }

/* ---------------------------------------------------------- QR editor */
.qr-editor { display: grid; grid-template-columns: minmax(0, 360px) minmax(0, 1fr); gap: 26px; align-items: start; }
.qr-preview { position: sticky; top: 82px; display: grid; gap: 12px; }
.qr-preview .qr-card { margin-inline: 0; }
.qr-controls fieldset { border: 0; margin: 0; padding: 22px; }
.qr-controls legend { padding: 0; }
input[type="color"] {
  width: 100%; height: 42px; padding: 3px; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--paper);
}
.swatches { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 8px; }
.swatch input { position: absolute; opacity: 0; pointer-events: none; }
.swatch span {
  display: block; text-align: center; padding: 9px 6px; font-size: .86rem;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  cursor: pointer; text-transform: capitalize; color: var(--ink-2);
}
.swatch input:checked + span {
  border-color: var(--signal); background: var(--signal-bg); color: var(--signal-ink); font-weight: 500;
}
.swatch input:focus-visible + span { outline: 2px solid var(--signal); outline-offset: 2px; }

@media (max-width: 860px) {
  .qr-editor { grid-template-columns: 1fr; }
  /* The preview is the thing being decided about — show it first on a phone. */
  .qr-preview { position: static; order: -1; }
}

/* ==========================================================================
   Matrix identity
   ========================================================================== */

/* A background layer rather than a canvas: two barely-visible column washes
   that drift very slowly. It reads as "terminal" without competing with the
   content, costs nothing to render, and stops entirely for anyone who has
   asked for reduced motion. */
body::before {
  content: "";
  position: fixed;
  inset: -20% 0 -20% 0;
  z-index: -2;
  pointer-events: none;
  background-image:
    repeating-linear-gradient(
      90deg,
      var(--signal-bg) 0 1px,
      transparent 1px 96px
    ),
    linear-gradient(
      180deg,
      transparent 0,
      var(--signal-bg) 40%,
      transparent 70%
    );
  background-size: 96px 100%, 100% 60vh;
  opacity: .5;
  animation: drift 38s linear infinite;
}

/* A single soft glow behind the header, so the top of the page has depth
   without a gradient on every surface. */
body::after {
  content: "";
  position: fixed;
  inset-block-start: -30vh;
  inset-inline: 0;
  height: 60vh;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(60% 50% at 50% 50%, var(--signal-bg), transparent 70%);
}

[data-theme="light"] body::before { opacity: .35; }
[data-theme="light"] body::after { display: none; }

@keyframes drift {
  from { background-position: 0 0, 0 -10vh; }
  to   { background-position: 0 100%, 0 70vh; }
}

/* ---- glass surfaces ------------------------------------------------------
   Blur is expensive and only means anything where content scrolls underneath,
   so it is limited to the two elements that actually overlap the page. */
.site-head {
  background: var(--glass);
  backdrop-filter: saturate(140%) blur(14px);
  -webkit-backdrop-filter: saturate(140%) blur(14px);
  border-block-end: 1px solid var(--glass-line);
}
.bulkbar {
  background: var(--glass);
  backdrop-filter: saturate(140%) blur(14px);
  -webkit-backdrop-filter: saturate(140%) blur(14px);
  border-color: var(--glass-line);
}

/* ---- cards ---------------------------------------------------------------
   One hairline, one soft shadow, and a green edge only on hover — the card
   itself is not the interesting part of the page. */
.card, .tile, .stat, .link-block, .table-wrap {
  background: linear-gradient(180deg, var(--paper-2), var(--paper));
  border-color: var(--line);
}
.tile { transition: border-color .16s ease, transform .16s ease; }
.tile:hover { border-color: var(--signal-dim); transform: translateY(-2px); }
.stat { transition: border-color .16s ease; }
.stat:hover { border-color: var(--signal-dim); }
.stat .n { color: var(--ink); }

/* The brand mark and the primary action are the only things that glow. */
.brand-mark { filter: drop-shadow(0 0 10px rgba(47, 227, 155, .35)); }
.btn-primary { box-shadow: var(--glow); }
[data-theme="light"] .btn-primary { box-shadow: none; }

/* Monospace anywhere an ID appears: these are strings people retype. */
.tile-id, .qr-card .qr-id, .meta-row .id { letter-spacing: .02em; }

/* ---- footer -------------------------------------------------------------- */
.site-foot { border-block-start: 1px solid var(--glass-line); }
.foot-brand { display: flex; align-items: center; gap: 8px; }
.foot-brand a { color: var(--ink-2); text-decoration: none; }
.foot-brand a:hover { color: var(--signal-ink); }

/* ---- selection and scrollbar --------------------------------------------- */
::selection { background: var(--signal-dim); color: var(--ink); }
* { scrollbar-color: var(--line) transparent; scrollbar-width: thin; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: var(--line); border-radius: 999px; }
::-webkit-scrollbar-thumb:hover { background: var(--signal-dim); }

/* ---- mobile --------------------------------------------------------------
   Touch targets stay at 44px and nothing is allowed to force a sideways
   scroll, which is the one layout bug a phone user cannot work around. */
html, body { overflow-x: hidden; max-width: 100%; }
@media (max-width: 560px) {
  .btn { min-height: 44px; }
  .nav a, .nav button { min-height: 44px; }
  .link-actions .btn { flex: 1 1 100%; }
  .doors { grid-template-columns: 1fr; }
  h1 { letter-spacing: -.02em; }
}

@media (prefers-reduced-motion: reduce) {
  body::before { animation: none; }
  .tile:hover { transform: none; }
}

/* ------------------------------------------------------------ upload state */
.dz-kinds { display: flex; gap: 8px; justify-content: center; margin-block-start: 12px; }
.dz-file { font-family: var(--font-mono); font-size: .84rem; color: var(--ink-2); margin: 10px 0 0; }
.dropzone video.dz-preview { max-height: 260px; width: 100%; border-radius: var(--radius-sm); }

.progress { display: grid; gap: 6px; }
.progress-bar {
  height: 8px; border-radius: 999px; overflow: hidden;
  background: var(--paper-2); border: 1px solid var(--line);
}
.progress-bar span {
  display: block; height: 100%; width: 0;
  background: var(--signal); border-radius: 999px;
  transition: width .2s ease;
}
[data-progress-text] { text-align: center; font-variant-numeric: tabular-nums; margin: 0; }

.eyebrow {
  font-family: var(--font-mono); font-size: .78rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--signal-ink); margin: 0 0 10px;
}
