/* photto.vn — tokens from DESIGN.md frontmatter, then components.
 * One light theme only (v1 has no dark mode). */

:root {
  /* colors — paper & ink chrome */
  --paper: #F6F0E4;
  --paper-2: #EDE3D0;
  --rule: #D9CCB2;
  --ink: #2B2520;
  --ink-2: #6E6357;
  --ink-3: #A3988A;
  --tape: #E9DCBC;
  --perforation: #E3DACB;
  /* the only accent */
  --grease: #E1532E;
  /* viewing area — neutral */
  --table: #F1F1F0;
  --glow: #FBFBFB;
  --mat: #E3E3E3;
  --print: #FFFFFF;
  --view-ink: #2E2E2E;
  --view-ink-2: #5A5A5A;
  --view-control: #F4F4F4;
  --ghost-line: #C9C9C9;
  --ghost-hole: #E2E2E2;
  --loupe: #2A2A2A;
  /* film */
  --film: #161616;
  --film-frame: #262626;
  --edge: #B5B5B5;
  --edge-dim: #8F8F8F;
  --edge-on: #E6E6E6;
  --film-line: #6A6A6A;
  --film-track: #3A3A3A;
  --logo-ground-dark: #1B1917;
  /* hue data swatches */
  --hue-r: #D9534A;
  --hue-y: #E0B43C;
  --hue-g: #5AA55A;
  --hue-c: #4CB0B8;
  --hue-b: #4F6FC4;
  --hue-m: #B45AB8;

  /* typography — system stacks, no webfonts */
  --font-serif: 'Iowan Old Style', 'Palatino Linotype', Palatino, 'Book Antiqua', Georgia, serif;
  --font-sans: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  --font-mono: ui-monospace, 'SF Mono', Menlo, Consolas, 'Liberation Mono', 'DejaVu Sans Mono', monospace;
  --font-hand: 'Marker Felt', 'Segoe Print', 'Bradley Hand', 'Chalkboard SE', cursive;

  --type-display: 600 30px/1.15 var(--font-serif);
  --type-title: 600 20px/1.2 var(--font-serif);
  --type-title-sm: 600 16px/1.25 var(--font-serif);
  --type-roll: 400 15px/1.2 var(--font-serif);
  --type-body: 400 13px/1.45 var(--font-sans);
  --type-body-sm: 400 12.5px/1.5 var(--font-sans);
  --type-caption: 400 11px/1.3 var(--font-sans);
  --type-button: 600 13px/1 var(--font-sans);
  --type-button-sm: 600 12px/1 var(--font-sans);
  --type-value: 400 11.5px/1.2 var(--font-mono);
  --type-value-lg: 700 13px/1.2 var(--font-mono);
  --type-label-caps: 500 11px/1.3 var(--font-mono);
  --type-stock-name: 700 11px/1 var(--font-mono);
  --type-edge-number: 700 11px/13px var(--font-mono);
  --type-edge-file: 400 11px/13px var(--font-mono);
  --type-hand: 400 15px/1 var(--font-hand);
  --ls-value-lg: 0.04em;
  --ls-label-caps: 0.16em;
  --ls-stock-name: 0.05em;
  --ls-edge-number: 0.03em;
  --ls-edge-file: 0.02em;

  /* shape */
  --rounded-none: 0;
  --rounded-xs: 2px;
  --rounded-sm: 3px;
  --rounded-md: 4px;
  --rounded-sheet: 16px;
  --rounded-full: 9999px;

  /* spacing */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 10px;
  --space-4: 14px;
  --space-5: 18px;
  --space-6: 26px;
  --header: 52px;
  --header-mobile: 44px;
  --control: 34px;
  --control-sm: 28px;
  --gutter-mobile: 14px;
  --col-stock: 296px;
  --col-slip: 344px;
  --print-mat: 8px;
  --hold: 36px;
  --slip-line: 34px;
  --loupe-size: 184px;
  --loupe-size-mobile: 96px;
  --sheet-peek: 292px;

  /* the visible viewport height, below mobile browser toolbars */
  --vh: 100vh;

  --line: 1.5px solid var(--ink);
  --shadow-paper: 0 16px 36px rgba(60, 45, 25, .22);
  --shadow-print: 0 1px 2px rgba(0, 0, 0, .12), 0 12px 28px rgba(0, 0, 0, .12);
  --shadow-sheet: 0 -12px 30px rgba(60, 45, 25, .18);

  /* slider-ruler marker: a triangle pointing down at the baseline */
  --mark-ink: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 10'%3E%3Cpath d='M0 0H12L6 10Z' fill='%232B2520'/%3E%3C/svg%3E");
  --mark-grease: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 10'%3E%3Cpath d='M0 0H12L6 10Z' fill='%23E1532E'/%3E%3C/svg%3E");

  /* grease-loop: the hand-drawn crayon ring, wax texture included */
  --grease-loop: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'%3E%3Cfilter id='wax' x='-10%25' y='-10%25' width='120%25' height='120%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.1' numOctaves='2' seed='3' result='n'/%3E%3CfeDisplacementMap in='SourceGraphic' in2='n' scale='2.4' xChannelSelector='R' yChannelSelector='G'/%3E%3C/filter%3E%3Cpath d='M8 52 C4 22 34 6 56 7 C84 8 97 28 95 52 C93 80 70 95 46 94 C20 93 5 76 7 50 C8 38 14 28 24 20' fill='none' stroke='%23E1532E' stroke-width='3.2' stroke-linecap='round' vector-effect='non-scaling-stroke' filter='url(%23wax)'/%3E%3C/svg%3E");
}

@supports (height: 100dvh) {
  :root { --vh: 100dvh; }
}

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

html, body { margin: 0; height: 100%; }

body {
  font: var(--type-body);
  color: var(--ink);
  background: var(--table);
  display: grid;
  grid-template-rows: var(--header) 1fr;
  min-height: 100%;
  -webkit-text-size-adjust: 100%;
}

h1, h2, h3, p, dl, dd, ol, fieldset { margin: 0; }
button, input { font: inherit; color: inherit; }
[hidden] { display: none !important; }

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

:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

.label-caps {
  font: var(--type-label-caps);
  letter-spacing: var(--ls-label-caps);
  text-transform: uppercase;
}

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

/* ------------------------------------------------------------- header */

.header {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: var(--space-5);
  padding: 0 var(--space-5);
  height: var(--header);
  background: var(--paper-2);
  border-bottom: var(--line);
}

.brand { display: flex; }
.logo { display: block; height: 36px; width: auto; }

.header-tools {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

/* ⓘ About trigger */
.about-trigger {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: var(--control-sm);
  padding: 0 var(--space-2) 0 var(--space-1);
  border: 0;
  border-radius: var(--rounded-md);
  background: transparent;
  font: var(--type-body-sm);
  color: var(--ink);
  white-space: nowrap;
  cursor: pointer;
}
.about-trigger[aria-expanded="true"] {
  background: var(--paper);
  box-shadow: inset 0 0 0 1.5px var(--ink);
}
.about-icon {
  width: 17px; height: 17px;
  display: grid; place-items: center;
  border: var(--line);
  border-radius: var(--rounded-full);
  font: 700 11px/1 var(--font-serif);
}
.about-icon::before { content: "i"; }

/* VI | EN */
.lang-toggle {
  display: inline-flex;
  height: var(--control-sm);
  padding: 0;
  border: var(--line);
  border-radius: var(--rounded-md);
  min-inline-size: 0;
}
.lang-toggle label { position: relative; display: flex; cursor: pointer; }
.lang-toggle label + label { border-left: var(--line); }
.lang-toggle input {
  position: absolute; inset: 0;
  margin: 0; opacity: 0;
  cursor: pointer;
}
.lang-toggle span {
  display: flex; align-items: center;
  padding: 0 9px;
  font: 700 11px/1 var(--font-mono);
  letter-spacing: .08em;
  color: var(--ink-2);
}
.lang-toggle label:first-child span { border-radius: 2.5px 0 0 2.5px; }
.lang-toggle label:last-child span { border-radius: 0 2.5px 2.5px 0; }
.lang-toggle input:checked + span { background: var(--ink); color: var(--paper); }
.lang-toggle input:focus-visible + span { outline: 2px solid var(--ink); outline-offset: -5px; }
.lang-toggle input:checked:focus-visible + span { outline-color: var(--paper); }

/* About popover */
.about-popover {
  position: absolute;
  top: calc(var(--header) + 8px);
  right: var(--space-5);
  width: 360px;
  padding: 16px 18px 14px;
  background: var(--paper);
  border: var(--line);
  border-radius: var(--rounded-sm);
  box-shadow: var(--shadow-paper);
  font: var(--type-body-sm);
  color: var(--ink);
}
.about-popover::before {
  content: "";
  position: absolute;
  top: -8px;
  left: calc(var(--arrow-x, 300px) - 6.5px);
  width: 13px; height: 13px;
  background: var(--paper);
  border-left: var(--line);
  border-top: var(--line);
  transform: rotate(45deg);
}
.about-title { font: var(--type-title-sm); margin-bottom: var(--space-1); }
.about-popover dl {
  display: grid;
  grid-template-columns: 96px 1fr;
  gap: 6px var(--space-3);
  margin: var(--space-3) 0;
  padding: var(--space-3) 0;
  border-top: 1px dashed var(--rule);
  border-bottom: 1px dashed var(--rule);
}
.about-popover dt {
  font: var(--type-label-caps);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-2);
  padding-top: 2px;
}
.about-popover dd { overflow-wrap: anywhere; }
.about-disclaimer { color: var(--ink-2); }

.text-link {
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--ink-3);
}
.text-link:hover { border-bottom-color: var(--ink); }
.text-link.mono { font: var(--type-value); }

/* ------------------------------------------------------------ buttons */

.button-secondary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: var(--control);
  padding: 0 var(--space-4);
  background: transparent;
  color: var(--ink);
  border: var(--line);
  border-radius: var(--rounded-md);
  font: var(--type-button);
  white-space: nowrap;
  cursor: pointer;
}
.button-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: var(--control);
  padding: 0 var(--space-4);
  background: var(--ink);
  color: var(--paper);
  border: var(--line);
  border-radius: var(--rounded-md);
  font: var(--type-button);
  white-space: nowrap;
  cursor: pointer;
}
.button-small { height: var(--control-sm); font: var(--type-button-sm); padding: 0 var(--space-3); }
.button-primary:disabled,
.button-secondary:disabled { opacity: .45; cursor: default; }
.button-primary:focus-visible,
.button-secondary:focus-visible,
button.text-link:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

button.text-link {
  padding: 0;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--ink-3);
  font: inherit;
  cursor: pointer;
}

/* "+ Thêm ảnh" */
.add-photo::before { content: "+"; margin-right: 5px; font-weight: 600; }

/* ----------------------------------------------- empty light table */

.table {
  position: relative;
  min-height: 0;
  background: radial-gradient(ellipse at 50% 35%, var(--glow) 0, var(--table) 75%);
  padding: var(--space-6);
  overflow: auto;
}

/* A file dragged over the window: wherever it lands, it is taken. */
.table.is-dragging::after {
  content: "";
  position: absolute;
  inset: 6px;
  border: 2.4px dashed var(--grease);
  pointer-events: none;
  z-index: 5;
}

.table > .notice { max-width: 820px; margin: 0 auto var(--space-5); }

.desk {
  max-width: 820px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.drop-zone {
  min-height: 210px;
  padding: var(--space-6) var(--space-4);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 7px;
  text-align: center;
  border: 2.4px dashed var(--grease);
  color: var(--view-ink-2);
}
.drop-title { font: var(--type-display); color: var(--view-ink); margin-bottom: var(--space-1); }
.drop-pick { font: var(--type-body-sm); color: var(--view-ink-2); margin-bottom: var(--space-1); }
.drop-pick .text-link { color: var(--view-ink); }
.engine-status { font: var(--type-body-sm); color: var(--view-ink-2); margin-top: var(--space-2); }

.privacy {
  display: flex;
  gap: var(--space-2);
  align-items: baseline;
  font: var(--type-body-sm);
  color: var(--view-ink);
}
.privacy-dot {
  flex: none;
  width: 7px; height: 7px;
  border-radius: var(--rounded-full);
  background: var(--grease);
  transform: translateY(-1px);
}

.ghost-strip {
  position: relative;
  height: 58px;
  display: flex;
  align-items: center;
  padding-left: var(--space-4);
  border: 1px dashed var(--ghost-line);
  border-radius: var(--rounded-xs);
  color: var(--view-ink-2);
}
.ghost-strip::before,
.ghost-strip::after {
  content: "";
  position: absolute;
  left: 6px; right: 6px;
  height: 6px;
  background: linear-gradient(90deg, transparent 4px, var(--ghost-hole) 4px 11px, transparent 11px) 0 0 / 15px 6px repeat-x;
}
.ghost-strip::before { top: 5px; }
.ghost-strip::after { bottom: 5px; }

.notice {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--paper);
  border: var(--line);
  border-radius: var(--rounded-sm);
  font: var(--type-body-sm);
  color: var(--ink);
}
.notice p { flex: 1; }

/* ------------------------------------------------- the bench: one photo */

.table.has-photo { padding: 0; overflow: hidden; background: var(--mat); }
.table.has-photo > .notice {
  position: absolute;
  z-index: 4;
  top: var(--space-4);
  left: 50%;
  transform: translateX(-50%);
  width: min(560px, calc(100% - 2 * var(--space-4)));
  margin: 0;
}

.bench {
  display: grid;
  grid-template-columns: var(--col-stock) minmax(0, 1fr) var(--col-slip);
  grid-template-areas: "stocks view slip";
  height: 100%;
  min-height: 0;
}

/* Stock column (stock-row, stock-tape, grease-loop) */
.stocks {
  position: relative; /* offsetParent of the rows: see revealSelected() */
  grid-area: stocks;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow-x: hidden;
  overflow-y: auto;
  padding: var(--space-4) 16px;
  background: var(--paper);
  border-right: var(--line);
}
.stocks-head {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  padding-bottom: 7px;
  border-bottom: var(--line);
}
.stocks-title { font: var(--type-title); }
.stocks-hint { margin-left: auto; color: var(--ink-2); letter-spacing: .1em; text-align: right; }

.stock-list { list-style: none; padding: 0; margin-top: var(--space-1); }
.stock-row:focus { outline: none; }
.stock-row:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

/* One radio group: the 13 stocks, then "Preset riêng" at the foot of the
   column (pushed down while there is room, after the stocks otherwise). */
.stock-group { flex: 1 0 auto; display: flex; flex-direction: column; }
.own-presets {
  margin-top: auto;
  padding-top: 12px;
  border-top: var(--line);
}
.own-title { color: var(--ink-2); margin-bottom: var(--space-1); }
.own-empty { font: var(--type-caption); color: var(--ink-2); padding: var(--space-1) 0 var(--space-2); }
.own-list { margin-top: 0; }
.own-list .stock-row:last-child { border-bottom: 0; }
/* stock-tape-own: white, dashed ink-3 border, no torn edge, no tilt */
.stock-tape.stock-tape-own {
  display: block; /* a block box, so a long NAME ends in "…" */
  max-width: 100%;
  line-height: 19px; /* 22 px less the borders: the text stays centred */
  text-align: center;
  background: var(--print);
  border: 1.5px dashed var(--ink-3);
  clip-path: none;
  transform: none;
  overflow: hidden;
  text-overflow: ellipsis;
}
.stock-row {
  display: grid;
  grid-template-columns: 18px 108px 1fr;
  gap: var(--space-2);
  align-items: center;
  min-height: 37px;
  padding: 5px 0;
  border-bottom: 1px dashed var(--rule);
  cursor: pointer;
}
.stock-num { font: var(--type-label-caps); letter-spacing: .02em; color: var(--ink-3); }
.stock-desc { font: var(--type-caption); color: var(--ink-2); }
.stock-row.is-on .stock-num { color: var(--grease); font-weight: 700; }
.stock-row.is-on .stock-desc { color: var(--ink); }

.stock-tape {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 108px;
  height: 22px;
  padding: 0 3px;
  background: var(--tape);
  color: var(--ink);
  font: var(--type-stock-name);
  letter-spacing: var(--ls-stock-name);
  white-space: nowrap;
  clip-path: polygon(3% 0, 97% 6%, 100% 30%, 98% 62%, 100% 100%, 2% 95%, 0 70%, 2% 38%);
  transform: rotate(var(--tilt, 0deg));
}
/* Circled: the tape straightens, loses its torn edge, gets the crayon ring. */
.stock-row.is-on .stock-tape { clip-path: none; transform: none; }
.stock-row.is-on .stock-tape::after {
  content: "";
  position: absolute;
  inset: -7px;
  background: var(--grease-loop) center / 100% 100% no-repeat;
  pointer-events: none;
}

/* Viewing area (preview-mat, print-frame): neutral grey only */
.view {
  grid-area: view;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  padding: var(--space-4) var(--space-6) var(--space-6);
  background: var(--mat);
  /* meta line, tools row and paddings; the loupe hangs below the photo */
  --print-max-h: calc(var(--vh) - var(--header) - 170px);
}
.view.loupe-on { --print-max-h: calc(var(--vh) - var(--header) - 222px); }
.preview-meta {
  display: flex;
  align-items: baseline;
  gap: 16px;
  min-width: 0;
  padding-bottom: var(--space-3);
  color: var(--view-ink-2);
  letter-spacing: .08em;
  white-space: nowrap;
}
.meta-frame { min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--view-ink); font-weight: 600; }
.meta-look { flex: none; margin-left: auto; }

.print-area {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* Sized from the photo's shape (--ar = w / h, --pw = w, set when it is
   painted): as large as fits, never larger than the photo itself. */
.print-frame {
  position: relative;
  display: block;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  width: min(
    100%,
    calc(var(--print-max-h) * var(--ar, 1) + 2 * var(--print-mat)),
    calc(var(--pw, 100000px) + 2 * var(--print-mat))
  );
  padding: var(--print-mat);
  background: var(--print);
  border-radius: var(--rounded-none);
  box-shadow: var(--shadow-print);
}
/* The full-resolution develop as stacked strip canvases (each <= 16 MP,
   for iOS Safari); CSS only scales the stack down. */
.print {
  display: block;
  -webkit-touch-callout: none;
  user-select: none;
}
.print canvas { display: block; width: 100%; height: auto; }

/* Over the print, the same box: the approximate preview while a slider
   moves, the original while "hold to compare" is held, the loupe ring. */
.print-overlay { position: absolute; inset: var(--print-mat); }
.print-frame.loupe-on .print-overlay { cursor: crosshair; touch-action: none; }
.print-approx { position: absolute; inset: 0; }
.print-approx canvas { display: block; width: 100%; height: 100%; }
.print-original {
  position: absolute; inset: 0;
  display: block;
  width: 100%; height: 100%;
  background: var(--print);
  pointer-events: none;
  -webkit-touch-callout: none;
  user-select: none;
}

/* Loupe 1:1 (loupe): the spot ring on the photo, the loupe beside it */
.loupe-ring {
  position: absolute;
  left: 50%; top: 50%;
  width: 40px; height: 40px;
  transform: translate(-50%, -50%);
  border: 1.5px dashed rgba(255, 255, 255, .95);
  border-radius: var(--rounded-full);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .25), inset 0 0 0 1px rgba(0, 0, 0, .25);
  cursor: grab;
}
.loupe-ring:focus-visible { outline: 2px solid var(--edge-on); outline-offset: 2px; }
.loupe {
  position: absolute;
  right: -38px; bottom: -58px;
  z-index: 2;
  width: var(--loupe-size); height: var(--loupe-size);
  padding: 10px;
  border-radius: var(--rounded-full);
  background: radial-gradient(circle at 35% 30%, #4a4a4a, var(--loupe) 70%);
  box-shadow: 0 18px 30px rgba(0, 0, 0, .32), inset 0 0 0 1px rgba(255, 255, 255, .08);
  pointer-events: none;
}
.loupe-glass {
  position: relative;
  width: 100%; height: 100%;
  border-radius: var(--rounded-full);
  overflow: hidden;
  box-shadow: 0 0 0 2px #111;
}
.loupe-glass canvas { display: block; width: 100%; height: 100%; image-rendering: pixelated; }
.loupe-glass::after {
  content: "";
  position: absolute; inset: 0;
  border-radius: var(--rounded-full);
  background:
    radial-gradient(ellipse at 30% 22%, rgba(255, 255, 255, .35), transparent 38%),
    radial-gradient(circle, transparent 62%, rgba(0, 0, 0, .28));
}
.loupe-tag {
  position: absolute;
  left: -8px; top: 18px;
  padding: 3px 7px;
  background: var(--print);
  color: var(--view-ink);
  font: 700 11px/1.2 var(--font-mono);
  border-radius: var(--rounded-sm);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .2);
}

/* Tools under the photo: hold to compare, Fit | Loupe 1:1 */
.view-tools {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding-top: var(--space-4);
  min-width: 0;
}
.view.loupe-on .view-tools { padding-top: 66px; }
.hold {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  height: var(--hold);
  padding: 0 15px 0 5px;
  border: 1.5px solid var(--view-ink);
  border-radius: var(--rounded-full);
  background: var(--view-control);
  color: var(--view-ink);
  font: var(--type-button);
  white-space: nowrap;
  cursor: pointer;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  touch-action: manipulation;
}
.hold-dot {
  flex: none;
  display: grid; place-items: center;
  width: 24px; height: 24px;
  border-radius: var(--rounded-full);
  background: var(--view-ink);
}
.hold-dot::after {
  content: "";
  width: 9px; height: 9px;
  border-radius: var(--rounded-full);
  border: 2px solid var(--view-control);
}
.hold.is-pressed { background: var(--view-ink); color: var(--view-control); }
.hold.is-pressed .hold-dot { background: var(--grease); }
.hold:focus-visible { outline: 2px solid var(--view-ink); outline-offset: 2px; }
.hold .hold-short, .segmented .seg-short { display: none; }

.segmented {
  display: inline-flex;
  flex: none;
  height: 32px;
  padding: 0;
  border: 1.5px solid var(--view-ink);
  border-radius: var(--rounded-md);
  min-inline-size: 0;
  overflow: hidden;
}
.segmented label { position: relative; display: flex; cursor: pointer; }
.segmented label + label { border-left: 1.5px solid var(--view-ink); }
.segmented input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; }
.segmented span {
  display: flex; align-items: center;
  padding: 0 11px;
  font: 500 12px/1 var(--font-sans);
  color: var(--view-ink);
  white-space: nowrap;
}
.segmented input:checked ~ span { background: var(--view-ink); color: var(--view-control); }
.segmented input:focus-visible ~ span { outline: 2px solid var(--view-control); outline-offset: -5px; }
.view-tools-hint { font: var(--type-caption); color: var(--view-ink-2); min-width: 0; }

.view-message { max-width: 420px; text-align: center; }

/* ------------------------------------------------- lab slip (lab-slip) */

.slip {
  grid-area: slip;
  position: relative;
  min-height: 0;
  overflow-y: auto;
  padding: var(--space-4) var(--space-5) var(--space-5);
  background-color: var(--paper);
  background-image: repeating-linear-gradient(180deg, transparent 0 33px, rgba(217, 204, 178, .42) 33px 34px);
  background-attachment: local;
  border-left: var(--line);
}
/* perforation along the top edge */
.slip::before {
  content: "";
  position: absolute;
  left: 8px; right: 8px; top: 4px;
  height: 6px;
  background: radial-gradient(circle, var(--perforation) 2.2px, transparent 2.6px) 0 0 / 10px 6px repeat-x;
}
.sheet-grab { display: none; }
.slip-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  padding: 4px 0 6px;
  border-bottom: var(--line);
}
.slip-title { font: var(--type-title); white-space: nowrap; }
.slip-title:focus { outline: none; }
.slip-frame { color: var(--ink-2); letter-spacing: .1em; white-space: nowrap; }
.slip-stock {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px var(--space-2);
  padding: 10px 0 8px;
  border-bottom: 1px dashed var(--rule);
}
.slip-stock-label { color: var(--ink-2); }
.slip-stock-name { font: var(--type-value-lg); letter-spacing: var(--ls-value-lg); }
.slip-note { font: var(--type-body-sm); color: var(--ink-2); white-space: nowrap; }
.slip-reset { margin-left: auto; font: var(--type-body-sm); white-space: nowrap; }
.slip-own { font: var(--type-body-sm); color: var(--ink-2); white-space: nowrap; }
.slip-own .text-link { font: var(--type-body-sm); }
.slip-own-sep::before { content: "·"; margin: 0 6px; }

/* Lưu / Lưu bản mới, then Tải .fs | Nhập .fs (mock: .acts, .two) */
.slip-acts { display: grid; gap: var(--space-2); padding-top: 12px; margin-top: 6px; }
.slip-save-row { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-2); }
.slip-save-row.is-own { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.slip-two { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-2); }
.slip-acts button { min-width: 0; padding: 0 var(--space-2); overflow: hidden; text-overflow: ellipsis; }

/* Tráng · Xuất, the end of the slip (mock: .divider + .dx, .r.q, .fname) */
.slip-export { margin-top: var(--space-5); }
.slip-divider {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: 4px;
  padding-top: 12px;
  border-top: var(--line);
  font: inherit;
}
.slip-divider .label-caps { color: var(--ink-2); white-space: nowrap; }
.dx-bar { display: block; flex: none; width: 110px; height: 9px; margin-left: auto; color: var(--ink); }
.export-name { margin: 4px 0 10px; font: var(--type-caption); color: var(--ink-2); overflow-wrap: anywhere; }
.slip-export-acts { display: grid; grid-template-columns: minmax(0, 1fr); }
.slip-export-acts button { min-width: 0; padding: 0 var(--space-2); overflow: hidden; text-overflow: ellipsis; }
.export-notice { margin-top: var(--space-3); }
.section-label { margin: 12px 0 2px; color: var(--ink-2); }

/* slider-row: label (key below) | ruler | value */
.slider-row {
  display: grid;
  grid-template-columns: 102px minmax(0, 1fr) 76px;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--control);
  font: var(--type-body-sm);
}
.slider-label { line-height: 1.2; min-width: 0; }
.slider-key {
  display: block;
  margin-top: 1px;
  font: var(--type-edge-file);
  letter-spacing: .05em;
  color: var(--ink-3);
  overflow: hidden;
  text-overflow: ellipsis;
}
.slider-value {
  justify-self: end;
  padding: 2px 6px;
  font: var(--type-value);
  white-space: nowrap;
  border: 1px solid var(--rule);
  border-radius: var(--rounded-xs);
  background: rgba(255, 255, 255, .55);
}
.slider-row.is-edited .slider-value {
  border-color: var(--grease);
  box-shadow: inset 0 -2px 0 var(--grease);
}

/* slider-ruler: ticks every 10 %, ink baseline, centre tick on two-way
   sliders. The marker is the range's own thumb, so dragging, keys and
   screen readers are the browser's. Ticks are inset by half the thumb so
   the marker's tip lands on them. */
.slider-ruler { position: relative; display: block; height: var(--control); }
.slider-ruler::before {
  content: "";
  position: absolute;
  left: 6px; right: 6px; top: calc(50% - 4px);
  height: 8.5px;
  background:
    linear-gradient(var(--ink), var(--ink)) 0 100% / 100% 1.5px no-repeat,
    linear-gradient(var(--ink-3), var(--ink-3)) 100% 0 / 1px 7px no-repeat,
    linear-gradient(90deg, var(--ink-3) 1px, transparent 1px) 0 0 / 10% 7px repeat-x;
  pointer-events: none;
}
.slider-ruler.bi::after {
  content: "";
  position: absolute;
  left: 50%; top: calc(50% - 9px);
  width: 1.5px; height: 11px;
  margin-left: -.75px;
  background: var(--ink);
  pointer-events: none;
}
.slider-input {
  -webkit-appearance: none;
  appearance: none;
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  margin: 0;
  background: transparent;
  cursor: pointer;
  touch-action: pan-y;
}
.slider-input::-webkit-slider-runnable-track { height: 100%; background: transparent; border: 0; }
.slider-input::-moz-range-track { height: 100%; background: transparent; border: 0; }
.slider-input::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 12px; height: 100%;
  border: 0; border-radius: 0;
  background: var(--mark-ink) 0 calc(50% - 2px) / 12px 10px no-repeat;
}
.slider-input::-moz-range-thumb {
  width: 12px; height: 100%;
  border: 0; border-radius: 0;
  background: var(--mark-ink) 0 calc(50% - 2px) / 12px 10px no-repeat;
}
.slider-row.is-edited .slider-input::-webkit-slider-thumb { background-image: var(--mark-grease); }
.slider-row.is-edited .slider-input::-moz-range-thumb { background-image: var(--mark-grease); }
.slider-input:focus { outline: none; }
.slider-input:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

/* slider-group: folded rows ("Theo từng màu", "Tách tông", ...) */
.slider-group { border-top: 1px dashed var(--rule); }
.slider-group:last-child { border-bottom: 1px dashed var(--rule); }
.group-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  height: var(--control);
  padding: 0;
  border: 0;
  background: none;
  font: var(--type-body-sm);
  color: var(--ink);
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
}
.group-caret { font-family: var(--font-mono); color: var(--ink-2); display: inline-block; width: 8px; }
.group-head[aria-expanded="true"] .group-caret { transform: rotate(90deg); }
.group-keys { font: var(--type-edge-file); color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.group-head.is-edited .group-title { box-shadow: inset 0 -2px 0 var(--grease); }
.group-swatches { margin-left: auto; display: flex; gap: 4px; flex: none; }
.swatch { width: 9px; height: 9px; border-radius: var(--rounded-full); box-shadow: inset 0 0 0 1px rgba(43, 37, 32, .3); }
.group-panel { padding-bottom: var(--space-2); }

/* Per hue: six dots, one radio group, then that hue's three sliders */
.hue-pick { display: flex; align-items: center; gap: var(--space-3); min-height: var(--control); }
.hue-dots { display: flex; gap: 7px; }
.hue-dot {
  position: relative;
  width: 20px; height: 20px;
  padding: 0;
  border: 0;
  border-radius: var(--rounded-full);
  cursor: pointer;
}
.hue-dot.hue-r { background: var(--hue-r); }
.hue-dot.hue-y { background: var(--hue-y); }
.hue-dot.hue-g { background: var(--hue-g); }
.hue-dot.hue-c { background: var(--hue-c); }
.hue-dot.hue-b { background: var(--hue-b); }
.hue-dot.hue-m { background: var(--hue-m); }
.hue-dot.is-on { box-shadow: 0 0 0 2px var(--paper), 0 0 0 3.5px var(--ink); }
/* adjusted: a crayon tick on the dot */
.hue-dot.is-edited::after {
  content: "";
  position: absolute;
  right: -4px; top: -4px;
  width: 9px; height: 9px;
  border-radius: var(--rounded-full);
  background: var(--grease);
  border: 1.5px solid var(--paper);
}
.hue-name { font: var(--type-body-sm); color: var(--ink-2); }

/* ------------------------------------------------------------ dialog */

.dialog-backdrop {
  position: fixed;
  inset: 0;
  z-index: 10;
  display: grid;
  place-items: center;
  padding: var(--space-4);
  background: rgba(43, 37, 32, .35);
}
.dialog {
  width: min(400px, 100%);
  padding: 18px;
  background: var(--paper);
  border: var(--line);
  border-radius: var(--rounded-sm);
  box-shadow: var(--shadow-paper);
}
.dialog-title { font: var(--type-title-sm); margin-bottom: var(--space-5); }
.dialog-actions { display: flex; justify-content: flex-end; gap: var(--space-2); flex-wrap: wrap; }
.dialog .dialog-actions { margin-top: var(--space-5); }
.dialog-title + .dialog-actions { margin-top: 0; }

/* text-field: the name typed freely; below it, the NAME that will be saved */
.field-label {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  margin-bottom: var(--space-1);
  font: var(--type-body-sm);
  color: var(--ink);
}
.text-field {
  display: block;
  width: 100%;
  height: var(--control);
  padding: 0 var(--space-3);
  background: var(--print);
  border: var(--line);
  border-radius: var(--rounded-md);
  font: var(--type-body);
}
.text-field:focus { outline: 2px solid var(--ink); outline-offset: 2px; }
.field-preview {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  min-height: 22px;
  margin: 6px 0 var(--space-4);
  overflow-wrap: anywhere;
}
.field-preview .label-caps { color: var(--ink-2); }
.name-preview { font: var(--type-value-lg); letter-spacing: var(--ls-value-lg); }
.desc-preview { font: var(--type-value); color: var(--ink); margin-bottom: 0; }
.desc-count { margin-left: auto; font: var(--type-value); color: var(--ink-2); }

/* The library notice (a .fs that could not be read, a save that failed) */
.preset-notice-file { font: var(--type-value); overflow-wrap: anywhere; }
.table > .preset-notice { max-width: 820px; margin: 0 auto var(--space-5); }
.view-error { font: var(--type-title-sm); color: var(--view-ink); }
.view-hint { margin-top: var(--space-2); font: var(--type-body-sm); color: var(--view-ink-2); }

/* Tablet: the Stock column folds into a strip of tapes above the view. */
@media (max-width: 1199px) {
  .bench {
    grid-template-columns: minmax(0, 1fr) var(--col-slip);
    grid-template-rows: auto minmax(0, 1fr);
    grid-template-areas: "stocks slip" "view slip";
  }
  .stocks {
    overflow-x: auto;
    overflow-y: hidden;
    padding: 0 var(--space-4);
    border-right: 0;
    border-bottom: var(--line);
    scrollbar-width: thin;
  }
  .stocks-head {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap;
  }
  .stocks { display: block; }
  .stock-group { flex-direction: row; align-items: stretch; gap: 9px; width: max-content; }
  .stock-list { display: flex; gap: 9px; margin: 0; width: max-content; }
  .own-presets {
    display: flex;
    align-items: center;
    gap: 9px;
    margin: 6px 0;
    padding: 0 0 0 9px;
    border-top: 0;
    border-left: var(--line);
  }
  .own-title {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap;
  }
  .own-empty { padding: 0; white-space: nowrap; }
  .own-list .stock-row { padding: 6px 0 4px; }
  .stock-row {
    position: relative; /* holds the visually hidden description */
    display: flex;
    min-height: 0;
    padding: 12px 0 10px;
    border: 0;
  }
  .stock-num { display: none; }
  .stock-desc {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap;
  }
  .stock-tape { width: auto; padding: 0 9px; transform: rotate(calc(var(--tilt, 0deg) * .6)); }
  .view { --print-max-h: calc(var(--vh) - var(--header) - 220px); }
  .view.loupe-on { --print-max-h: calc(var(--vh) - var(--header) - 272px); }
  .view-tools-hint { display: none; }
}

/* -------------------------------------------------------------- phone */

@media (max-width: 767px) {
  body { grid-template-rows: var(--header-mobile) 1fr; }
  .header { height: var(--header-mobile); padding: 0 var(--gutter-mobile); gap: var(--space-3); }
  .logo { height: 30px; }
  .header-tools { gap: var(--space-3); }
  .about-trigger { padding: 0 var(--space-1); }
  .about-label {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap;
  }
  .about-popover dl { grid-template-columns: 84px 1fr; }
  .table { padding: var(--space-5) var(--gutter-mobile); }
  .drop-zone { min-height: 180px; }

  /* Header order on a phone: logo, ⓘ, VI | EN, then a round "+". */
  .add-photo {
    order: 3;
    width: 30px; height: 30px;
    padding: 0;
    border-radius: var(--rounded-full);
  }
  .add-photo::before { margin: 0; font-size: 17px; font-weight: 400; }
  .add-label {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap;
  }

  /* One column: the view first, then the strip of tapes. */
  .table.has-photo { overflow: auto; }
  .bench {
    height: auto;
    min-height: 100%;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto;
    grid-template-areas: "view" "stocks";
    align-content: start;
    padding-bottom: var(--sheet-peek); /* scroll clear of the sheet */
  }
  .stocks { padding: 0 var(--gutter-mobile); border-top: var(--line); border-bottom: 0; }
  .view {
    padding: var(--space-2) var(--gutter-mobile) var(--space-3);
    --print-max-h: max(160px, calc(var(--vh) - var(--header-mobile) - var(--sheet-peek) - 150px));
  }
  .view.loupe-on { --print-max-h: max(140px, calc(var(--vh) - var(--header-mobile) - var(--sheet-peek) - 180px)); }
  .print-frame { --print-mat: 5px; }

  .loupe { width: var(--loupe-size-mobile); height: var(--loupe-size-mobile); padding: 6px; right: -12px; bottom: -30px; }
  .loupe-tag { font-size: 11px; left: -6px; top: 4px; padding: 2px 5px; }
  .view-tools { gap: var(--space-2); padding-top: var(--space-3); }
  .view.loupe-on .view-tools { padding-top: 36px; }
  .hold { height: 32px; font-size: 12px; padding-right: 12px; }
  .hold-dot { width: 22px; height: 22px; }
  .hold .hold-long, .segmented .seg-long { display: none; }
  .hold .hold-short, .segmented .seg-short { display: flex; }
  .segmented { height: 30px; }

  /* The lab slip is a bottom sheet: it peeks with the three main
     sliders; the handle opens it all the way. */
  .slip {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 3;
    height: var(--sheet-peek);
    padding: 0 var(--space-5) var(--space-4);
    border-left: 0;
    border-top: var(--line);
    border-radius: var(--rounded-sheet) var(--rounded-sheet) 0 0;
    box-shadow: var(--shadow-sheet);
    overscroll-behavior: contain;
    transition: height .2s ease;
  }
  .slip.is-open { height: calc(var(--vh) - var(--header-mobile) - 24px); }
  .slip::before { display: none; }
  .sheet-grab {
    position: sticky;
    top: 0;
    z-index: 1;
    display: block;
    width: calc(100% + 2 * var(--space-5));
    height: 22px;
    margin: 0 calc(-1 * var(--space-5));
    padding: 0;
    border: 0;
    background: var(--paper);
    cursor: grab;
    touch-action: none;
  }
  .sheet-grab::before {
    content: "";
    display: block;
    width: 38px; height: 4px;
    margin: 0 auto;
    border-radius: 2px;
    background: var(--ink-3);
  }
  .slip-head { padding-top: 0; }
  .slip-title { font-size: 17px; }
  .slip-frame { display: none; }
  .slip-stock { padding: 6px 0; }
  .section-label { margin-top: 6px; }
  .slider-row { grid-template-columns: 84px minmax(0, 1fr) 72px; min-height: 32px; }
  .text-field { font-size: 16px; } /* iOS zooms into smaller fields */
}

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

/* Touch: 44 px hit areas even where the drawing is smaller. */
@media (pointer: coarse) {
  .about-trigger, .lang-toggle label, .add-photo { position: relative; }
  .add-photo::after {
    content: "";
    position: absolute;
    left: 50%; top: 50%;
    width: max(100%, 44px); height: 44px;
    transform: translate(-50%, -50%);
  }
  .about-trigger::after {
    content: "";
    position: absolute;
    left: 50%; top: 50%;
    width: max(100%, 44px); height: 44px;
    transform: translate(-50%, -50%);
  }
  /* Each half of VI | EN is itself 44 px wide, so the taller hit areas
     below never overlap sideways. */
  .lang-toggle label { min-width: 44px; }
  .lang-toggle span { flex: 1; justify-content: center; }
  .lang-toggle label::after {
    content: "";
    position: absolute;
    left: 0; right: 0; top: 50%;
    height: 44px;
    transform: translateY(-50%);
  }
  .slider-row { min-height: 44px; }
  .slider-ruler { height: 44px; }
  .group-head, .hue-pick { min-height: 44px; }
  .hue-dot::before {
    content: "";
    position: absolute;
    left: 50%; top: 50%;
    width: 27px; height: 44px;
    transform: translate(-50%, -50%);
  }
  .hold, .segmented label, .sheet-grab, .slip-reset { position: relative; }
  .segmented label::after, .slip-reset::after, .sheet-grab::after {
    content: "";
    position: absolute;
    left: 50%; top: 50%;
    width: max(100%, 44px); height: 44px;
    transform: translate(-50%, -50%);
  }
}
