/* Advantech Selector — shared styles for the wizard and the admin console. */

:root {
  color-scheme: light dark;
  --bg: #f4f5f7;
  --surface: #ffffff;
  --surface-2: #fafbfc;
  --line: #dfe3e8;
  --line-soft: #eceff3;
  --ink: #1b2027;
  --ink-2: #5a636e;
  --ink-3: #8b949f;
  --brand: #d0021b;
  --brand-ink: #ffffff;
  --brand-soft: #fdeced;
  --ok: #1a7f4b;
  --ok-soft: #e7f5ed;
  --warn: #9a6300;
  --warn-soft: #fdf3e0;
  --bad: #b3261e;
  --bad-soft: #fdeceb;
  --radius: 10px;
  --shadow: 0 1px 2px rgba(16,24,40,.06), 0 8px 24px -16px rgba(16,24,40,.28);
  --tour-dim: rgba(12, 16, 24, .55);
  --font: "Inter", "Noto Sans TC", "Noto Sans JP", -apple-system, BlinkMacSystemFont,
          "Segoe UI", "Hiragino Sans", "Yu Gothic UI", "Microsoft JhengHei", sans-serif;
  --mono: ui-monospace, SFMono-Regular, "JetBrains Mono", Consolas, monospace;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #101317;
    --surface: #191d23;
    --surface-2: #1f242b;
    --line: #2c333c;
    --line-soft: #242a31;
    --ink: #e8ebef;
    --ink-2: #a6b0bb;
    --ink-3: #78828d;
    --brand: #ff5f6d;
    --brand-ink: #24070a;
    --brand-soft: #33191c;
    --ok: #56cc8f;
    --ok-soft: #13291f;
    --warn: #e0ac54;
    --warn-soft: #2c2314;
    --bad: #ff8177;
    --bad-soft: #2e1817;
    --shadow: 0 1px 2px rgba(0,0,0,.4), 0 10px 30px -18px rgba(0,0,0,.9);
    --tour-dim: rgba(0, 0, 0, .66);
  }
}

* { box-sizing: border-box; }

/* A class that sets `display` outranks the browser's own [hidden] rule, so the
   hidden attribute silently stops working on .board, .btn and friends. */
[hidden] { display: none !important; }

html, body { margin: 0; padding: 0; }
body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; }
button, input, select, textarea { font: inherit; color: inherit; }

/* ---------------------------------------------------------------- chrome */

.topbar {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap; row-gap: 8px;
  padding: 12px 24px;
  background: color-mix(in srgb, var(--surface) 97%, transparent);
  backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid var(--line);
}
.brand {
  display: flex; align-items: center; gap: 12px; font-weight: 640;
  letter-spacing: -.01em; text-decoration: none; color: inherit;
}
.brand .logo { height: 22px; width: auto; display: block; flex: none; }
.brand-rule { width: 1px; height: 22px; background: var(--line); flex: none; }

/* Official raster assets usually ship on a white background. Add
   class="logo logo--plate" to the <img> to sit them on a white card so they
   stay legible in the dark theme. */
.brand .logo--plate {
  background: #fff; padding: 4px 7px; border-radius: 6px; height: 30px;
}
.brand small { display: block; font-weight: 450; font-size: 12px; color: var(--ink-3); }
.pg-min { display: none; }
.spacer { flex: 1 1 auto; }

/* On a wide screen the secondary controls are simply part of the bar; the ⋯
   button does not exist. The wrapper only becomes a real box on a phone. */
.navrest { display: contents; }
.topbar .nav-more { display: none; }

.seg { display: flex; gap: 2px; padding: 2px; background: var(--surface-2); border: 1px solid var(--line); border-radius: 8px; }
.seg button {
  border: 0; background: transparent; padding: 4px 10px; border-radius: 6px;
  font-size: 13px; color: var(--ink-2); cursor: pointer;
}
.seg button[aria-pressed="true"] { background: var(--surface); color: var(--ink); box-shadow: var(--shadow); font-weight: 560; }

/* The language picker. Three buttons cost the header about 150px, which is
   what pushed it onto two rows on a 1440-wide laptop; a select is one control
   wide and names each language in that language, which is what a reader
   looking for their own language scans for. */
.langsel {
  appearance: none;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  font: inherit; font-size: 13px; line-height: 1.2;
  padding: 6px 26px 6px 11px; border-radius: 8px; cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 12px top 50%, right 7px top 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.langsel:hover { border-color: var(--ink-3); }
.langsel:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
/* The list itself is drawn by the browser and does not inherit the page's
   colours, so it is told them explicitly or a dark page opens a white menu. */
.langsel option { background: var(--surface); color: var(--ink); }

.btn {
  display: inline-flex; align-items: center; gap: 7px;
  border: 1px solid var(--line); background: var(--surface);
  padding: 7px 13px; border-radius: 8px; cursor: pointer; font-size: 13.5px;
  text-decoration: none; white-space: nowrap;
}
.btn:hover { border-color: var(--ink-3); }
.btn.primary { background: var(--brand); border-color: var(--brand); color: var(--brand-ink); font-weight: 560; }
.btn.primary:hover { filter: brightness(1.06); }
.btn.ghost { background: transparent; border-color: transparent; color: var(--ink-2); }
.btn.ghost:hover { background: var(--surface-2); color: var(--ink); }
.btn.danger { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 35%, var(--line)); background: transparent; }
.btn:disabled { opacity: .5; cursor: not-allowed; }

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

.card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow);
}

.shell { max-width: 1600px; margin: 0 auto; padding: 0 24px; }
main.shell { padding-top: 22px; padding-bottom: 48px; }

/* Two layouts, chosen by the reader: "wide" puts the conditions in a bar above
   a full-width product grid; "split" is the earlier side-by-side view. */
.stage { display: block; }
.qcol { display: none; }

body[data-layout="split"] .stage {
  display: grid; grid-template-columns: 380px minmax(0, 1fr);
  gap: 22px; align-items: start;
}
body[data-layout="split"] .qcol {
  display: flex; flex-direction: column; gap: 12px;
  position: sticky; top: 112px; max-height: calc(100vh - 132px); overflow: auto;
  padding-right: 2px;
}
body[data-layout="split"] .conds { display: none; }
body[data-layout="split"] #btn-board { display: none; }
body[data-layout="split"] .condwrap { justify-content: flex-end; padding-top: 8px; padding-bottom: 8px; }
@media (max-width: 1100px) {
  body[data-layout="split"] .stage { grid-template-columns: minmax(0, 1fr); }
  body[data-layout="split"] .qcol { position: static; max-height: none; }
}

.seg.layouts button { display: grid; place-items: center; padding: 4px 9px; }
.seg.layouts svg { width: 15px; height: 13px; display: block; }
.seg.layouts .lf { fill: currentColor; opacity: .32; }
.seg.layouts .ls { fill: currentColor; opacity: .85; }
.seg.layouts button[aria-pressed="true"] { color: var(--brand); background: var(--surface); }

/* question cards for the split layout */
.q { padding: 15px 16px; }
.q h2 { font-size: 14.5px; margin: 0 0 3px; letter-spacing: -.01em; }
.q .help { margin: 0 0 11px; font-size: 12.5px; color: var(--ink-2); }
.q .tag {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-3); border: 1px solid var(--line); border-radius: 999px;
  padding: 1px 7px; margin-left: 7px; vertical-align: 2px; font-weight: 500;
}

/* ------------------------------------------------------------ condition bar */

/* The condition bar sits directly under the header. Its offset is the
   header's real height, which JS measures -- the header is two rows on a
   phone and one on a desktop, so a fixed number is wrong on one of them. */
.condbar {
  position: sticky; top: var(--topbar-h, 53px); z-index: 30;
  background: color-mix(in srgb, var(--surface) 97%, transparent);
  backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid var(--line);
}
.condwrap { display: flex; align-items: flex-start; gap: 14px; padding-top: 11px; padding-bottom: 11px; }
.conds { display: flex; flex-wrap: wrap; gap: 7px; flex: 1 1 auto; min-width: 0; }
.condwrap > .btn { flex: none; }

.cond {
  display: inline-flex; align-items: baseline; gap: 7px; cursor: pointer;
  border: 1px solid var(--line); background: var(--surface-2);
  border-radius: 999px; padding: 5px 13px; max-width: 100%;
}
.cond:hover { border-color: var(--ink-3); }
.cond[aria-expanded="true"] { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
.cond .ck { font-size: 11.5px; color: var(--ink-3); white-space: nowrap; }
.cond .cv {
  font-size: 13px; font-weight: 560; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; max-width: 22ch;
}
.cond.empty { border-style: dashed; background: transparent; }
.cond.empty .cv { font-weight: 450; color: var(--ink-3); }
.cond.lead { border-color: var(--brand); background: var(--brand-soft); }
.cond.lead .ck { color: color-mix(in srgb, var(--brand) 75%, var(--ink)); }
.cond.lead .cv { color: var(--brand); font-weight: 600; }

.sizebtn { flex: none; font-variant-numeric: tabular-nums; }
.sizebtn b { color: var(--brand); }

/* popover holding one question's options */
.pop {
  position: fixed; z-index: 60; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 18px 48px -18px rgba(8, 10, 14, .45); width: min(560px, calc(100vw - 24px));
  padding: 16px 18px 18px; max-height: min(74vh, 620px); overflow: auto;
}
.pop h2 { font-size: 15px; margin: 0 0 3px; letter-spacing: -.01em; }
.pop .help { margin: 0 0 13px; font-size: 12.5px; color: var(--ink-2); }
.pop .tag {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-3); border: 1px solid var(--line); border-radius: 999px;
  padding: 1px 7px; margin-left: 7px; vertical-align: 2px; font-weight: 500;
}
.pop .clear { margin-top: 12px; }

.pills { display: flex; flex-wrap: wrap; gap: 7px; }
.pill {
  display: inline-flex; flex-direction: column; gap: 2px;
  border: 1px solid var(--line); background: var(--surface-2);
  border-radius: 9px; padding: 7px 12px; cursor: pointer; text-align: left; max-width: 100%;
}
.pill:hover { border-color: var(--ink-3); }
.pill[aria-pressed="true"] { border-color: var(--brand); background: var(--brand-soft); box-shadow: inset 0 0 0 1px var(--brand); }
.pill .l { font-size: 13.5px; }
.pill .h { font-size: 11.5px; color: var(--ink-2); }

.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 9px; }
.opt-card {
  border: 1px solid var(--line); background: var(--surface-2);
  border-radius: 10px; padding: 11px; cursor: pointer; text-align: left;
  display: flex; flex-direction: column; gap: 7px;
}
.opt-card:hover { border-color: var(--ink-3); }
.opt-card[aria-pressed="true"] { border-color: var(--brand); background: var(--brand-soft); box-shadow: inset 0 0 0 1px var(--brand); }
.opt-card .l { font-size: 13px; font-weight: 560; line-height: 1.35; }
.opt-card .h { font-size: 11.5px; color: var(--ink-2); line-height: 1.45; }

svg.art { width: 100%; height: auto; display: block; }
svg.art-icon { width: 40px; height: 36px; }
.a-frame { fill: color-mix(in srgb, var(--ink) 4%, transparent); stroke: var(--line); }
.a-corner { stroke: var(--ink-3); stroke-width: 1.5; fill: none; }
.a-fill { fill: color-mix(in srgb, var(--ink) 55%, transparent); }
.a-bg { fill: color-mix(in srgb, var(--surface) 90%, transparent); }
.a-box { fill: none; stroke: var(--brand); stroke-width: 2; stroke-dasharray: 4 3; }
.a-stroke { fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.opt-card .a-stroke { color: var(--ink-2); }
.opt-card[aria-pressed="true"] .a-stroke { color: var(--brand); }
.opt-card[aria-pressed="true"] .a-fill { fill: var(--brand); }

/* ------------------------------------------------- floating question board */

.board {
  position: fixed; z-index: 70;
  width: 430px; height: min(600px, 78vh);
  min-width: 300px; min-height: 160px;
  max-width: calc(100vw - 20px); max-height: calc(100vh - 20px);
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 26px 70px -22px rgba(8, 10, 14, .55), 0 2px 8px rgba(8, 10, 14, .12);
  resize: both;
}
.board.min { height: auto !important; min-height: 0; resize: none; }
.board.dragging { user-select: none; }

.board-head {
  display: flex; align-items: center; gap: 9px;
  padding: 9px 10px 9px 12px; border-bottom: 1px solid var(--line);
  background: var(--surface-2); cursor: grab; touch-action: none; flex: none;
}
.board.dragging .board-head { cursor: grabbing; }
.board.min .board-head { border-bottom: 0; }
.board-head strong { font-size: 13.5px; }
.board-head .btn { padding: 2px 9px; font-size: 14px; line-height: 1.2; }
.board-prog { font-size: 11.5px; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.grip {
  width: 11px; height: 14px; flex: none; opacity: .5;
  background-image: radial-gradient(currentColor 1px, transparent 1.2px);
  background-size: 5px 5px; color: var(--ink-3);
}

.board-body { padding: 4px 14px 14px; overflow: auto; flex: 1; }
.board.min .board-body { display: none; }

.bq { padding: 10px 0; border-bottom: 1px solid var(--line-soft); }
.bq:last-child { border-bottom: 0; }
.bq h3 {
  font-size: 12px; margin: 0 0 6px; font-weight: 620;
  display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap;
}
.bq h3 .full { font-size: 11px; color: var(--ink-3); font-weight: 400; }
.bq.done h3 { color: var(--ink); }
.bq.todo h3 { color: var(--ink-2); }
.bq.todo h3::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: var(--brand); flex: none; align-self: center;
}
.bopts { display: flex; flex-wrap: wrap; gap: 5px; }
.bopt {
  display: inline-flex; align-items: center; gap: 5px; cursor: pointer;
  border: 1px solid var(--line); background: var(--surface-2);
  border-radius: 7px; padding: 3px 9px; font-size: 12px; text-align: left;
}
.bopt:hover { border-color: var(--ink-3); }
.bopt[aria-pressed="true"] {
  border-color: var(--brand); background: var(--brand-soft);
  color: var(--brand); font-weight: 560;
}
.bopt svg.art { width: 30px; height: 21px; flex: none; }
.bopt svg.art-icon { width: 18px; height: 16px; flex: none; }

@media (max-width: 640px) {
  .board { width: calc(100vw - 20px); height: min(70vh, 560px); resize: none; }
}

/* ---------------------------------------------------------------- results */

.sechead {
  display: flex; align-items: baseline; gap: 10px;
  margin: 26px 0 13px; font-size: 15px; font-weight: 620; letter-spacing: -.01em;
}
.sechead:first-child { margin-top: 4px; }
.sechead .n { font-size: 13px; font-weight: 450; color: var(--ink-3); }
.sechead .why { font-size: 12.5px; font-weight: 450; color: var(--ink-2); }

.pgrid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(252px, 1fr));
  gap: 16px; align-items: stretch;
}

.pcard {
  position: relative;
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: var(--shadow); overflow: hidden; display: flex; flex-direction: column;
}
.pcard:hover { border-color: var(--ink-3); }
.pcard.blocked { opacity: .78; }
.pcard.blocked:hover { opacity: 1; }
/* the product link stretches over the whole card */
.pcard .plink { text-decoration: none; color: inherit; }
.pcard .plink::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.pcard:hover .plink .nm { color: var(--brand); }
.pcard .pfoot { position: relative; z-index: 2; }

.shot {
  --shot-h: 168px;
  height: var(--shot-h); background: #fff; display: grid; place-items: center;
  border-bottom: 1px solid var(--line-soft); position: relative; overflow: hidden;
}
/* The height cap has to be an absolute length. A percentage max-height resolves
   against the grid area, whose row is content-sized and therefore indefinite, so
   the browser drops the cap entirely -- a square product photo then renders at
   its natural 220px inside a 168px box and gets clipped top and bottom. Only the
   landscape shots happened to fit, which is why the bug looked selective. */
.shot img {
  max-width: 84%; max-height: calc(var(--shot-h) * 0.84);
  width: auto; height: auto; object-fit: contain; display: block;
}
.shot.empty::after {
  content: attr(data-sku); font-family: var(--mono); font-size: 13px;
  color: #9aa4b0; letter-spacing: .04em;
}
.rank {
  position: absolute; top: 9px; left: 9px; z-index: 1;
  background: var(--ink); color: var(--bg); border-radius: 999px;
  font-size: 11px; font-weight: 650; padding: 2px 8px; font-variant-numeric: tabular-nums;
}

.pbody { padding: 13px 15px 14px; display: flex; flex-direction: column; gap: 9px; flex: 1; }
.pcard .nm { font-weight: 620; font-size: 14px; line-height: 1.35; display: block; }
.pcard .sku { font-family: var(--mono); font-size: 11px; color: var(--ink-3); display: block; margin-top: 3px; }
.pcard .cat { font-size: 11.5px; color: var(--ink-3); }

.pspecs { display: flex; flex-wrap: wrap; gap: 5px; }
.pspecs span {
  font-size: 11px; border: 1px solid var(--line); border-radius: 999px;
  padding: 1px 8px; color: var(--ink-2); background: var(--surface-2);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.pspecs b { color: var(--ink); font-weight: 600; }

.score { display: flex; align-items: center; gap: 8px; margin-top: auto; padding-top: 3px; }
.bar { flex: 1; height: 5px; border-radius: 999px; background: var(--line-soft); overflow: hidden; }
.bar i { display: block; height: 100%; background: var(--ok); border-radius: 999px; }
.pcard.blocked .bar i { background: var(--ink-3); }
.score .pct { font-size: 12px; font-variant-numeric: tabular-nums; color: var(--ink-2); min-width: 32px; text-align: right; }

.blockers { font-size: 11.5px; color: var(--bad); line-height: 1.45; }
.perfnote {
  font-size: 11px; color: var(--ink-3); line-height: 1.45;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden;
}
.modfit { font-size: 11.5px; color: var(--ink-2); }
.modfit.ok { color: var(--ok); }

.pfoot {
  border-top: 1px solid var(--line-soft); padding: 9px 15px 10px;
  display: flex; flex-direction: column; gap: 6px;
}
.pfoot a { font-size: 11.5px; color: var(--ink-2); }
details.why summary {
  font-size: 11.5px; color: var(--ink-3); cursor: pointer; list-style: none;
}
details.why summary::-webkit-details-marker { display: none; }
details.why summary::before { content: "▸ "; }
details.why[open] summary::before { content: "▾ "; }
.reason { display: flex; gap: 7px; font-size: 11.5px; padding: 3px 0; align-items: baseline; }
.reason .dot { width: 6px; height: 6px; border-radius: 50%; flex: none; margin-top: 4px; }
.reason.pass .dot { background: var(--ok); }
.reason.fail .dot { background: var(--bad); }
.reason.unknown .dot { background: var(--ink-3); opacity: .5; }
.reason .rk { color: var(--ink-2); }
.reason .rv { margin-left: auto; font-variant-numeric: tabular-nums; color: var(--ink-3); text-align: right; }
.reason.fail .rv { color: var(--bad); }

.splash {
  border: 1px dashed var(--line); border-radius: 12px; padding: 26px 24px;
  color: var(--ink-2); font-size: 14px; line-height: 1.6; margin-bottom: 22px;
  background: var(--surface-2);
}
.splash strong { display: block; color: var(--ink); font-size: 16px; margin-bottom: 5px; letter-spacing: -.01em; }
.empty { color: var(--ink-2); font-size: 13.5px; line-height: 1.6; }
.empty strong { display: block; color: var(--ink); margin-bottom: 4px; }

/* -------------------------------------------------- sizing report (dialog) */

.metric { display: grid; grid-template-columns: 1fr auto; gap: 2px 12px; padding: 7px 0; border-bottom: 1px solid var(--line-soft); }
.metric:last-child { border-bottom: 0; }
.metric .k { font-size: 13px; color: var(--ink-2); }
.metric .v { font-size: 14px; font-weight: 620; font-variant-numeric: tabular-nums; text-align: right; }
.metric .v .u { font-weight: 450; font-size: 12px; color: var(--ink-3); margin-left: 3px; }
.metric .n { grid-column: 1 / -1; font-size: 12px; color: var(--ink-3); line-height: 1.5; }
.dlgsec { font-size: 12px; text-transform: uppercase; letter-spacing: .07em; color: var(--ink-3); font-weight: 620; margin: 22px 0 6px; }
.dlgsec:first-child { margin-top: 0; }

.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
  font-size: 12px; border: 1px solid var(--line); border-radius: 999px;
  padding: 3px 9px; background: var(--surface-2); color: var(--ink-2);
}
.chip b { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }

.warnlist { display: flex; flex-direction: column; gap: 8px; }
.warnitem {
  font-size: 13px; line-height: 1.5; color: var(--ink);
  background: var(--warn-soft); border: 1px solid color-mix(in srgb, var(--warn) 30%, transparent);
  border-radius: 8px; padding: 9px 11px;
}

/* ------------------------------------------------------- the narrow header

   Eleven controls need about 1600px. Below that they wrap, and on a phone --
   400 CSS pixels -- they wrapped into three rows and pushed the first product
   off the screen entirely, which is the one thing this page exists to show.
   So below 1600px the bar keeps what a visitor came for (the line switcher and
   Contact sales) and everything else moves behind ⋯. */
@media (max-width: 1599px) {
  .topbar .nav-more { display: inline-flex; padding: 7px 11px; font-size: 15px; line-height: 1; }
  .navrest {
    display: none;
    position: absolute; top: calc(100% + 6px); right: 12px; z-index: 41;
    flex-direction: column; align-items: stretch; gap: 6px;
    padding: 10px; min-width: 190px;
    background: var(--surface); border: 1px solid var(--line);
    border-radius: 12px; box-shadow: 0 12px 30px rgb(0 0 0 / .28);
  }
  .navrest[data-open] { display: flex; }
  /* Inside the menu every row is a full-width line, so the eye runs down one
     edge instead of hunting across a grid of pills. */
  .navrest .btn, .navrest .langsel { justify-content: flex-start; text-align: left; width: 100%; }
  .navrest .seg.layouts { align-self: flex-start; }
}

/* The wide/split switch has nothing to switch below 1100px -- the split layout
   already collapses to one column there -- so it does not earn a row. */
@media (max-width: 1100px) {
  .navrest .seg.layouts { display: none; }
}

@media (max-width: 820px) {
  .topbar { gap: 10px; padding: 10px 14px; }
  .brand .logo { height: 19px; }
  .brand small { font-size: 11px; }
  #lines button { padding: 4px 8px; font-size: 12.5px; }

  /* The line switcher gets a row of its own. Left to wrap on its own terms it
     lands wherever the width happens to allow, which is two rows in Chinese and
     three in English -- "Intelligent connectivity" is simply longer than
     「網路與通訊」. Given the whole row it is two rows in every language, and it
     scrolls sideways rather than stacking when the names are long. */
  #lines {
    order: 10; flex-basis: 100%; max-width: 100%;
    overflow-x: auto; scrollbar-width: none;
  }
  #lines::-webkit-scrollbar { display: none; }
  #lines button { flex: none; white-space: nowrap; }
}

@media (max-width: 640px) {
  /* The page's own name is the one thing on the bar the visitor can also read
     in the address bar; the answered count is not repeated anywhere. */
  .brand #brand-title { display: none; }
  .brand small { display: inline; }
  .brand-rule { display: none; }
  /* The first row carries the logo, the count, Contact sales and ⋯ -- four
     things that fit at 390px only once they stop being desktop-sized. At the
     old size "Contact sales" overshot by four pixels and pushed ⋯ onto a row
     of its own, which is how English ended up a row taller than Chinese. */
  .topbar { gap: 8px; }
  .topbar .btn { padding: 6px 10px; font-size: 12.5px; }
  .topbar .nav-more { padding: 6px 9px; }
  .pg-full { display: none; }
  .pg-min { display: inline; font-variant-numeric: tabular-nums; }
}

/* ------------------------------------------------- the conditions on a phone

   Wrapped, the chips took three rows and about 135px of a 664px screen. In one
   swipeable row they take 46px, and "All questions" is deliberately outside the
   scroller so it stays put no matter how far along the row you are -- it is the
   way to see everything at once, so it must never be the thing that scrolled
   off. The strip fades at its right edge, which is what says there is more. */
@media (max-width: 1100px) {
  .condwrap { align-items: center; gap: 9px; }
  .conds {
    flex-wrap: nowrap; overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x proximity; scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    padding-right: 14px;
    mask-image: linear-gradient(to right, #000 calc(100% - 22px), transparent 100%);
  }
  .conds::-webkit-scrollbar { display: none; }
  .conds > * { flex: none; scroll-snap-align: start; }
}

/* On a phone every pixel the two pinned buttons give up is a pixel of visible
   strip, so the sizing button keeps its number and drops its label. */
@media (max-width: 640px) {
  .sizebtn .sz-l { display: none; }
  .condwrap > .btn { padding: 6px 11px; font-size: 13px; }
  .cond { padding: 4px 11px; }
  .cond .ck { font-size: 11px; }
  .cond .cv { font-size: 12.5px; max-width: 11ch; }
}

@media (max-width: 640px) {
  .gate-top { top: 10px; right: 10px; gap: 7px; }
  .gate-inner { padding-top: 40px; }
  .shell { padding: 0 14px; }
  .cond .cv { max-width: 14ch; }
  .pgrid { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 11px; }
  .shot { --shot-h: 118px; }
}

/* ---------------------------------------------------------------- admin */

.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line); margin-bottom: 18px; }
.tabs button {
  border: 0; background: transparent; padding: 9px 14px; cursor: pointer;
  font-size: 14px; color: var(--ink-2); border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.tabs button[aria-selected="true"] { color: var(--ink); border-bottom-color: var(--brand); font-weight: 560; }

table.grid { width: 100%; border-collapse: collapse; font-size: 13.5px; }
table.grid th, table.grid td { text-align: left; padding: 9px 12px; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
table.grid th { font-size: 12px; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-3); font-weight: 600; }
table.grid tr:hover td { background: var(--surface-2); }
table.grid td.num { font-variant-numeric: tabular-nums; text-align: right; }

.field { display: block; margin-bottom: 12px; }
.field > span { display: block; font-size: 12.5px; color: var(--ink-2); margin-bottom: 4px; }
.field input[type=text], .field input[type=number], .field input[type=password],
.field select, .field textarea {
  width: 100%; padding: 8px 10px; border: 1px solid var(--line);
  border-radius: 8px; background: var(--surface-2);
}
.field textarea { min-height: 74px; resize: vertical; font-family: var(--mono); font-size: 12.5px; }
.field.row { display: flex; align-items: center; gap: 8px; }
.field.row > span { margin: 0; }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 14px; }
.grid3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 0 14px; }
@media (max-width: 700px) { .grid2, .grid3 { grid-template-columns: 1fr; } }

dialog {
  border: 1px solid var(--line); border-radius: 12px; padding: 0;
  background: var(--surface); color: var(--ink); max-width: 860px; width: calc(100% - 32px);
  box-shadow: 0 24px 64px -24px rgba(0,0,0,.5);
}
dialog::backdrop { background: rgba(8,10,14,.5); backdrop-filter: blur(2px); }
dialog .dlg-head { padding: 16px 20px; border-bottom: 1px solid var(--line); display: flex; align-items: center; gap: 12px; }
dialog .dlg-head h2 { margin: 0; font-size: 16px; }
dialog .dlg-body { padding: 20px; max-height: min(68vh, 640px); overflow: auto; }
dialog.wide { max-width: 980px; }

/* ------------------------------------------------ first-run help and tour */

#intro { max-width: 760px; }
.intro-head { padding: 26px 28px 4px; }
.intro-head h2 { margin: 0 0 7px; font-size: 21px; letter-spacing: -.02em; }
.intro-head p { margin: 0; color: var(--ink-2); font-size: 14px; line-height: 1.6; }
.intro-steps { padding: 18px 28px 4px; display: flex; flex-direction: column; gap: 14px; }
.intro-step { display: grid; grid-template-columns: 30px minmax(0, 1fr); gap: 14px; align-items: start; }
.intro-step .n {
  width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center;
  background: var(--brand); color: var(--brand-ink); font-size: 13px; font-weight: 700;
  margin-top: 1px;
}
.intro-step h3 { margin: 3px 0 4px; font-size: 14.5px; }
.intro-step p { margin: 0; font-size: 13px; color: var(--ink-2); line-height: 1.6; }
.intro-note {
  margin: 16px 28px 0; padding: 10px 13px; border-radius: 8px;
  background: var(--surface-2); border: 1px solid var(--line-soft);
  font-size: 12.5px; color: var(--ink-2); line-height: 1.55;
}
.intro-foot {
  display: flex; align-items: center; gap: 8px;
  padding: 18px 28px 22px;
}
@media (max-width: 560px) {
  .intro-head, .intro-steps, .intro-foot { padding-left: 18px; padding-right: 18px; }
  .intro-note { margin-left: 18px; margin-right: 18px; }
  .intro-foot { flex-wrap: wrap; }
}

/* The tour dims everything but the step's target. The dimming is the huge
   box-shadow spread of #tourhole, a fixed box laid over the target: a shadow
   paints over any stacking context without lifting the target out of its own,
   never affects layout or scrollbars, and is not hit-tested, so the page below
   stays clickable. The hole itself carries the ring. */
.tourmask { position: fixed; inset: 0; z-index: 87; cursor: pointer; }
.tourhole {
  position: fixed; z-index: 88; pointer-events: none; border-radius: 12px;
  box-shadow: 0 0 0 100vmax var(--tour-dim), 0 0 0 1px rgba(255, 255, 255, .28) inset;
  outline: 3px solid var(--brand); outline-offset: 0;
  animation: tourpulse 1.8s ease-in-out infinite;
  transition: top .2s ease, left .2s ease, width .2s ease, height .2s ease;
}
@keyframes tourpulse {
  0%, 100% { outline-color: var(--brand); }
  50% { outline-color: color-mix(in srgb, var(--brand) 40%, transparent); }
}
/* Marks the element the current step points at; the spotlight does the work. */
.tour-target { border-radius: 10px; }
@media (prefers-reduced-motion: reduce) {
  .tourhole { animation: none; transition: none; }
}

.tourtip {
  position: fixed; z-index: 95; width: min(370px, calc(100vw - 24px));
  padding: 15px 17px 13px;
  box-shadow: 0 20px 52px -18px rgba(8, 10, 14, .5), 0 2px 8px rgba(8, 10, 14, .14);
}
.tourtip .tour-step { font-size: 11px; color: var(--ink-3); letter-spacing: .04em; }
.tourtip h3 { margin: 5px 0 6px; font-size: 15px; letter-spacing: -.01em; }
.tourtip p { margin: 0; font-size: 13px; color: var(--ink-2); line-height: 1.6; }
.tour-hint { margin: 9px 0 0; font-size: 11.5px; color: var(--ink-3); }
.tour-foot { display: flex; align-items: center; gap: 7px; margin-top: 12px; }
.cfg-cap { padding: 14px 20px 0; }
.cfg-foot {
  padding: 13px 20px 16px; border-top: 1px solid var(--line);
  background: var(--surface-2); display: flex; flex-direction: column; gap: 8px;
}
.cfg-row {
  display: flex; align-items: center; gap: 14px;
  padding: 8px 0; border-bottom: 1px solid var(--line-soft);
}
.cfg-row:last-child { border-bottom: 0; }
.cfg-row.nofit { opacity: .55; }
.cfg-name { flex: 1; min-width: 0; font-size: 13.5px; }
.cfg-name a { text-decoration: none; }
.cfg-name a:hover { color: var(--brand); }
.cfg-name .sku { font-family: var(--mono); font-size: 11px; color: var(--ink-3); margin-left: 7px; }
.cfg-meta { font-size: 11.5px; color: var(--ink-3); margin-top: 2px; }
.cfg-why { font-size: 11.5px; color: var(--bad); margin-top: 2px; }
.stepper { display: flex; align-items: center; gap: 4px; flex: none; width: 92px; justify-content: flex-end; }
.stepper button {
  width: 26px; height: 26px; border-radius: 7px; border: 1px solid var(--line);
  background: var(--surface); cursor: pointer; font-size: 15px; line-height: 1;
}
.stepper button:hover:not(:disabled) { border-color: var(--brand); color: var(--brand); }
.stepper button:disabled { opacity: .4; cursor: not-allowed; }
.stepper b { min-width: 20px; text-align: center; font-variant-numeric: tabular-nums; }
.cfg-err {
  font-size: 12.5px; line-height: 1.5; color: var(--bad);
  background: var(--bad-soft); border: 1px solid color-mix(in srgb, var(--bad) 28%, transparent);
  border-radius: 8px; padding: 8px 11px;
}
.cfg-err code { font-size: 11.5px; margin-right: 5px; }
.cfg-ok {
  font-size: 12.5px; color: var(--ok); background: var(--ok-soft);
  border: 1px solid color-mix(in srgb, var(--ok) 28%, transparent);
  border-radius: 8px; padding: 8px 11px; font-weight: 560;
}
.pfoot .cfgbtn { padding: 3px 9px; font-size: 11.5px; align-self: flex-start; }

dialog .dlg-foot { padding: 14px 20px; border-top: 1px solid var(--line); display: flex; gap: 8px; justify-content: flex-end; }

/* ---------------------------------------------------------------- the gate */

.gate {
  position: fixed; inset: 0; z-index: 120; overflow: auto;
  background: var(--bg);
  display: grid; place-items: center; padding: 40px 20px;
  isolation: isolate;
}
/* The front door carries a picture of what these products are for; the working
   screens stay plain. Two layers keep it a background rather than a picture:
   the photograph at a low opacity, and a wash of the page colour poured over
   the middle so the wordmark, the heading and the cards sit on clean ground
   and the image survives only around the edges. Both are fixed to the viewport
   so scrolling a narrow window does not drag the image with the content. */
.gate::before, .gate::after {
  content: ""; position: fixed; inset: 0; pointer-events: none;
}
.gate::before {
  background: url("bg.jpg") center / cover no-repeat;
  opacity: .11; filter: saturate(.55);
  z-index: -2;
}
.gate::after {
  background: radial-gradient(ellipse 78% 72% at 50% 45%,
    var(--bg) 0%, color-mix(in srgb, var(--bg) 86%, transparent) 52%,
    color-mix(in srgb, var(--bg) 40%, transparent) 100%);
  z-index: -1;
}
/* The photograph is a dark night scene: on a light page it would read as a
   grey smudge, so it is dialled back further there. */
@media (prefers-color-scheme: light) {
  .gate::before { opacity: .07; }
}
:root[data-theme="light"] .gate::before { opacity: .07; }
:root[data-theme="dark"] .gate::before { opacity: .11; }

.gate-inner { width: 100%; max-width: 900px; text-align: center; position: relative; }

/* A way into the admin console from the front door, so nobody has to remember
   the /admin path. Quiet on purpose: it is for the two people who maintain the
   catalog, not for the visitor the page is built around. */
/* Both front-door controls sit together in the top right: the language the
   page is read in, and the way into the console for whoever maintains it. */
.gate-top {
  position: absolute; top: 18px; right: 20px; z-index: 2;
  display: flex; align-items: center; gap: 10px;
}
.gate-top .langsel {
  background-color: color-mix(in srgb, var(--surface) 70%, transparent);
  backdrop-filter: blur(6px);
}
.gate-admin {
  font-size: 13px; color: var(--ink-3); text-decoration: none;
  padding: 7px 13px; border: 1px solid var(--line); border-radius: 999px;
  background: color-mix(in srgb, var(--surface) 70%, transparent);
  backdrop-filter: blur(6px);
}
.gate-admin:hover, .gate-admin:focus-visible {
  color: var(--ink); border-color: var(--ink-3); outline: none;
}
.gate-logo { width: 132px; height: auto; margin: 0 auto 26px; display: block; }
.gate-inner h1 { margin: 0 0 8px; font-size: 26px; letter-spacing: -.02em; }
.gate-inner > p, .gate-inner p { margin: 0 0 30px; color: var(--ink-2); font-size: 14.5px; }
.gate-grid {
  display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.gate-card {
  display: flex; flex-direction: column; align-items: flex-start; gap: 7px;
  padding: 24px 22px 20px; text-align: left; cursor: pointer;
  border: 1px solid var(--line); border-radius: 14px; background: var(--surface);
  color: inherit; font: inherit; box-shadow: var(--shadow);
  transition: border-color .15s, transform .15s;
}
.gate-card:hover, .gate-card:focus-visible {
  border-color: var(--brand); transform: translateY(-2px); outline: none;
}
.gate-icon {
  font-size: 26px; line-height: 1; color: var(--brand);
  display: block; height: 34px;
}
.gate-icon svg.art-line { width: 38px; height: 34px; }
/* The line marks follow the brand colour, like the glyphs they replace. */
svg.art-line .a-fill { fill: currentColor; }
svg.art-line .a-stroke { stroke: currentColor; }
/* Dots punched out of the filled die, so they read at 38px. */
svg.art-line .a-bg-dot { fill: var(--surface); }
/* In the top bar the mark sits inline with the line's name. svg.art is a block
   by default, which would put the mark on a line of its own and make the whole
   header tall enough to wrap. */
.seg svg.art-line {
  display: inline-block; width: 16px; height: 15px;
  vertical-align: -2px; margin-right: 5px;
}
.gate-card strong { font-size: 17px; letter-spacing: -.01em; }
.gate-help { font-size: 13px; color: var(--ink-2); line-height: 1.6; flex: 1; }
.gate-go {
  margin-top: 10px; font-size: 13px; font-weight: 560; color: var(--brand);
}
.gate-card:hover .gate-go::after, .gate-card:focus-visible .gate-go::after { content: " \2192"; }
/* Nothing behind the gate should be reachable while it is up. */
body.gated { overflow: hidden; }

/* ----------------------------------------------------------- the tour button

   Bottom right, above everything, out of the reading path. It hides whenever
   it would be in the way -- while the gate is up, while the tour it starts is
   running, and on paper. */
.tourfab {
  position: fixed; z-index: 55;
  right: max(20px, env(safe-area-inset-right));
  bottom: max(20px, env(safe-area-inset-bottom));
  display: inline-flex; align-items: stretch;
  border: 1px solid var(--line); border-radius: 999px; background: var(--surface);
  box-shadow: 0 10px 26px -8px rgb(0 0 0 / .45), 0 2px 6px rgb(0 0 0 / .18);
  transition: transform .15s, border-color .15s;
}
.tourfab:hover, .tourfab:focus-within { border-color: var(--brand); transform: translateY(-2px); }
.tourfab button {
  border: 0; background: transparent; color: var(--ink);
  font: inherit; font-size: 13.5px; font-weight: 560; cursor: pointer;
}
.tourfab-go {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 6px 10px 14px; border-radius: 999px 0 0 999px;
}
.tourfab-i { color: var(--brand); font-size: 15px; line-height: 1; }
/* The way out is part of the thing itself: no hunting in a settings page for
   how to stop something that is floating over your work. */
.tourfab-x {
  padding: 10px 13px 10px 8px; border-radius: 0 999px 999px 0;
  color: var(--ink-3); font-size: 16px; line-height: 1;
}
.tourfab-x:hover { color: var(--ink); }
.tourfab-go:focus-visible, .tourfab-x:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }
body.gated .tourfab { display: none; }

/* On a phone the label goes: down there it would sit across a product card,
   and the mark plus its aria-label says enough. */
@media (max-width: 640px) {
  .tourfab { right: 14px; bottom: 14px; }
  .tourfab #tourfab-l { display: none; }
  /* Two halves in one small pill: each needs a finger's worth of width, or
     "start the tour" and "never show this again" are one slip apart. */
  .tourfab button { min-width: 42px; min-height: 44px; justify-content: center; }
  .tourfab-go { padding: 0; gap: 0; }
  .tourfab-x { padding: 0; font-size: 17px; }
  .tourfab-i { font-size: 17px; }
  /* A hairline between them, so the two targets read as two. */
  .tourfab-x { border-left: 1px solid var(--line); }
}

@media print { .tourfab { display: none; } }

/* ------------------------------------------------------ contact sales form */

#contact { max-width: 620px; }
.ct-sub { margin: 0 0 12px; font-size: 13.5px; color: var(--ink-2); line-height: 1.6; }
.ct-what { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 16px; }
.ct-note { margin: 12px 0 0; font-size: 12px; color: var(--ink-3); }
#contact textarea {
  width: 100%; padding: 9px 11px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--surface-2); color: inherit; font: inherit; resize: vertical;
}
#contact textarea:focus, #contact input:focus { outline: 2px solid var(--brand); outline-offset: -1px; }
/* The honeypot has to be reachable by a naive bot and invisible to a person:
   off-screen rather than display:none, which some bots skip. */
.ct-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* ----------------------------------------------- admin settings (mailboxes) */

.seth { margin: 0 0 4px; font-size: 15px; }
.setsub {
  margin: 20px 0 8px; font-size: 12px; font-weight: 600; color: var(--ink-3);
  text-transform: uppercase; letter-spacing: .06em;
}
.sethelp { margin: 0 0 14px; font-size: 12.5px; color: var(--ink-2); line-height: 1.6; }
.setfoot { display: flex; align-items: center; gap: 8px; margin-top: 16px; flex-wrap: wrap; }
.setfoot input { padding: 7px 10px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--surface-2); color: inherit; min-width: 200px; }
.linepick {
  padding: 6px 10px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--surface); color: inherit; font-size: 13px; margin-right: 14px;
}

/* Completeness: a model is usable once its required fields are in. */
.needs {
  margin-left: 7px; font-size: 10.5px; padding: 1px 7px; border-radius: 999px;
  background: var(--warn-soft); color: var(--warn); white-space: nowrap;
}
.corebar {
  font-size: 11.5px; padding: 3px 10px; border-radius: 999px;
  background: var(--warn-soft); color: var(--warn); white-space: nowrap;
}
.corebar.done { background: var(--ok-soft); color: var(--ok); }
.incfilter {
  display: inline-flex; align-items: center; gap: 7px; margin-bottom: 12px;
  font-size: 12.5px; color: var(--ink-2); cursor: pointer;
}
#sec-_core > summary, .dn[data-goto="sec-_core"] .dn-l { font-weight: 640; }

/* ------------------------------------------------- spreadsheet round-trip */

.sheetrep { margin-top: 16px; }
.tallies { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 12px; }
.tally {
  font-size: 12px; padding: 3px 10px; border-radius: 999px;
  border: 1px solid var(--line); color: var(--ink-2); background: var(--surface-2);
}
.tally.ok { border-color: var(--ok); color: var(--ok); background: var(--ok-soft); }
.tally.bad { border-color: var(--bad); color: var(--bad); background: var(--bad-soft); }
.sheettbl { margin-top: 6px; }
.sheettbl td { vertical-align: top; font-size: 12.5px; }
.sheettbl td small { display: block; color: var(--ink-3); font-size: 11px; margin-top: 1px; }
.sheettbl td:first-child { width: 1%; white-space: nowrap; }
.tag-add, .tag-update, .tag-delete, .tag-error {
  font-size: 10.5px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  padding: 2px 8px; border-radius: 999px; white-space: nowrap;
}
.tag-add { background: var(--ok-soft); color: var(--ok); }
.tag-update { background: var(--brand-soft); color: var(--brand); }
.tag-delete { background: var(--bad-soft); color: var(--bad); }
.tag-error { background: var(--warn-soft); color: var(--warn); }
.cellchg { margin-bottom: 2px; }
.cellchg s { color: var(--ink-3); }
.cellchg b { color: var(--ink); }
.okline { color: var(--ok); font-size: 13px; margin: 10px 0 0; }

/* -------------------------------------------------------------- sign-in */

.login { max-width: 400px; margin: 8vh auto; padding: 24px; }
.login h2 { margin: 0 0 14px; font-size: 17px; }
.loginseg { display: flex; margin-bottom: 16px; }
.loginseg button { flex: 1; justify-content: center; }
.loginhelp { margin: 0 0 14px; font-size: 12.5px; color: var(--ink-2); line-height: 1.6; }
.btn.wide { width: 100%; justify-content: center; margin-top: 8px; }
.loginfoot { display: flex; gap: 6px; margin-top: 12px; flex-wrap: wrap; }
.otpinput {
  font: 600 22px/1.2 var(--mono); letter-spacing: .3em; text-align: center;
}

.whoami { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; color: var(--ink-2); }
.rolechip {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em;
  border: 1px solid var(--line); border-radius: 999px; padding: 1px 7px; color: var(--ink-3);
}
.warnpill {
  font-size: 12px; color: var(--warn); background: var(--warn-soft);
  border-radius: 999px; padding: 4px 11px;
}

/* Recipient picker: group chips you tick, plus a box for loose addresses. */
.rcpt-groups { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 12px; }
.rcpt-groups label {
  display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
  padding: 5px 11px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface-2); font-size: 13px;
}
.rcpt-groups label.on { border-color: var(--brand); background: var(--brand-soft); color: var(--brand); }
.rcpt-groups input { margin: 0; }
.rcpt-gc {
  font-size: 11px; font-variant-numeric: tabular-nums; color: var(--ink-3);
  border-left: 1px solid var(--line); padding-left: 7px;
}
.rcpt-groups label.on .rcpt-gc { color: var(--brand); border-color: currentColor; }
.rcpt textarea, .grpcard textarea {
  width: 100%; padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--surface-2); color: inherit; font: inherit; resize: vertical;
}
.grpcard, .catcard { border: 1px solid var(--line-soft); border-radius: 10px; padding: 12px 14px; }
.grphead { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.grphead .grp-name {
  flex: 1; padding: 7px 10px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--surface-2); color: inherit; font-weight: 560;
}
.cathead { font-weight: 560; font-size: 13.5px; margin-bottom: 10px; }

.enqtext {
  margin: 0 0 6px; padding: 12px 14px; border: 1px solid var(--line-soft); border-radius: 9px;
  background: var(--surface-2); font: 12.5px/1.6 var(--mono); color: var(--ink);
  white-space: pre-wrap; word-break: break-word; max-height: 320px; overflow: auto;
}
.skuadd { display: flex; gap: 8px; margin-bottom: 10px; }
.skuadd input { flex: 1; padding: 7px 10px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--surface-2); color: inherit; }
table.grid input[type="email"] {
  width: 100%; padding: 5px 8px; border: 1px solid var(--line); border-radius: 7px;
  background: var(--surface-2); color: inherit; font-size: 13px;
}

/* Table of contents down the left of the product editor. The form scrolls in
   .dlg-body; the list is sticky inside that scroll port, so it stays put while
   the fields move beside it. Every entry is type="button" - inside
   <form method="dialog"> a plain button submits the form and closes it. */
.dlgsplit {
  display: grid; grid-template-columns: 200px minmax(0, 1fr);
  gap: 26px; align-items: start;
}
.dlgtoc {
  position: sticky; top: -20px; align-self: start;
  display: flex; flex-direction: column; gap: 1px;
  padding: 20px 0; margin: -20px 0;
  background: var(--surface);
  /* Match the scroll port so a longer contents list scrolls on its own rather
     than running past the bottom of the dialog. */
  max-height: min(68vh, 640px); overflow: auto;
}
.dlgtoc h4 {
  margin: 0 0 9px 12px; font-size: 11px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3);
}
.dlgmain { border-left: 1px solid var(--line-soft); padding-left: 26px; min-width: 0; }

.dn {
  display: flex; align-items: baseline; gap: 8px; width: 100%; text-align: left;
  padding: 6px 10px 6px 11px; border: 0; border-left: 2px solid transparent;
  border-radius: 0 8px 8px 0; background: transparent; color: var(--ink-2);
  font-size: 13px; line-height: 1.45; cursor: pointer;
}
.dn:hover { background: var(--surface-2); color: var(--ink); }
.dn.on {
  border-left-color: var(--brand); background: var(--brand-soft);
  color: var(--brand); font-weight: 560;
}
.dn-i {
  flex: none; width: 15px; font-size: 11px; font-variant-numeric: tabular-nums;
  color: var(--ink-3); text-align: right;
}
.dn.on .dn-i { color: var(--brand); }
.dn-l { flex: 1 1 auto; min-width: 0; }
.dn-n {
  flex: none; font-size: 11px; font-variant-numeric: tabular-nums;
  color: var(--ink-3); opacity: .9;
}
.dn-n.none { opacity: .5; }
.dn.on .dn-n { color: var(--brand); }
.dn-act {
  margin: 10px 0 0 11px; width: auto; justify-content: center;
  border: 1px solid var(--line); border-radius: 8px; padding: 5px 10px;
  font-size: 12px; color: var(--ink-2);
}
.dn-act:hover { border-color: var(--brand); }

.dlgsec-h {
  font-size: 13px; margin: 18px 0 10px; color: var(--ink-3);
  text-transform: uppercase; letter-spacing: .06em;
}
.dlgsec, .attrgroup, .dlgsec-h { scroll-margin-top: 12px; }

/* Too narrow for two columns: the contents run across the top instead. */
@media (max-width: 820px) {
  .dlgsplit { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .dlgtoc {
    position: static; margin: 0; padding: 0 0 12px;
    flex-direction: row; flex-wrap: wrap; gap: 6px;
    border-bottom: 1px solid var(--line);
  }
  .dlgtoc h4 { width: 100%; margin-left: 0; }
  .dn {
    width: auto; border-left: 0; border-radius: 999px;
    border: 1px solid var(--line); background: var(--surface-2); padding: 4px 10px;
  }
  .dn.on { border-color: var(--brand); }
  .dn-act { margin: 0; }
  .dlgmain { border-left: 0; padding-left: 0; }
}

/* Rows in the admin tables open their editor; the buttons at the end still do
   their own thing. */
table.grid tr.rowlink { cursor: pointer; }
table.grid tr.rowlink:focus-visible {
  outline: 2px solid var(--brand); outline-offset: -2px;
}

.attrgroup { border: 1px solid var(--line-soft); border-radius: 10px; margin-bottom: 12px; }
.attrgroup > summary { padding: 10px 14px; cursor: pointer; font-weight: 560; font-size: 13.5px; }
.attrgroup > div { padding: 0 14px 12px; }
.multibox { display: flex; flex-wrap: wrap; gap: 6px; }
.seg.kindbar { flex-wrap: wrap; width: fit-content; max-width: 100%; }
.seg.kindbar button { font-size: 12.5px; }

.cardset { border: 1px solid var(--line); border-radius: 9px; background: var(--surface-2); }
.cardset-q {
  width: 100%; border: 0; border-bottom: 1px solid var(--line); background: transparent;
  padding: 8px 11px; border-radius: 9px 9px 0 0;
}
.cardset-list { max-height: 260px; overflow: auto; padding: 8px 10px 10px; }
.cardset-grp { margin-bottom: 8px; }
.cardset-grp > b { display: block; font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-3); margin: 4px 0 4px; }
.cardset-grp label {
  display: flex; align-items: baseline; gap: 7px; font-size: 12.5px; padding: 2px 0; cursor: pointer;
}
.cardset-grp label code { font-size: 11.5px; flex: none; }
.cardset-grp label .cs-name { color: var(--ink-2); }
.cardset-grp label .cs-why { margin-left: auto; font-size: 11px; color: var(--bad); text-align: right; padding-left: 10px; }

/* colour-coded against what the automatic slot rules say */
.cardset-grp label.fit code,
.cardset-grp label.fit .cs-name { color: var(--ok); }
.cardset-grp label.nofit code,
.cardset-grp label.nofit .cs-name { color: var(--bad); opacity: .85; }

.cardset-legend {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 8px 11px; border-bottom: 1px solid var(--line); font-size: 11.5px;
}
.cs-key { display: inline-flex; align-items: center; gap: 5px; color: var(--ink-2); }
.cs-key::before { content: ""; width: 8px; height: 8px; border-radius: 2px; }
.cs-key.fit::before { background: var(--ok); }
.cs-key.nofit::before { background: var(--bad); }
.cs-tally { color: var(--ink-3); font-variant-numeric: tabular-nums; }
.cs-only { margin-left: auto; display: inline-flex; align-items: center; gap: 5px; color: var(--ink-2); cursor: pointer; }

.multibox label { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; border: 1px solid var(--line); border-radius: 7px; padding: 4px 9px; background: var(--surface-2); cursor: pointer; }
.multibox input { margin: 0; }

.toast {
  position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%);
  background: var(--ink); color: var(--bg); padding: 9px 16px; border-radius: 999px;
  font-size: 13.5px; box-shadow: var(--shadow); z-index: 90;
}
.muted { color: var(--ink-3); }
.err { color: var(--bad); font-size: 13px; }
.stack { display: flex; flex-direction: column; gap: 14px; }
/* never put display:flex on a <td> - it drops the cell out of table layout */
.rowbtns { display: flex; gap: 4px; justify-content: flex-end; }
table.grid td:has(> .rowbtns) { white-space: nowrap; width: 1%; }

/* ------------------------------------------------------------------ print
   Paper gets its own document (#printsheet, built by renderPrintSheet): the
   answers as text, then the sizing derivation, then the products as tables.
   Everything the screen uses is hidden rather than reflowed. */

#printsheet { display: none; }

@media print {
  @page { size: A4; margin: 14mm 12mm 12mm; }

  body { background: #fff; color: #000; }
  body > *, dialog { display: none !important; }
  #printsheet {
    display: block !important; font-size: 10pt; line-height: 1.45;
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }

  .ps-top {
    display: flex; align-items: flex-start; gap: 14px;
    border-bottom: 1.5pt solid #000; padding-bottom: 8px; margin-bottom: 14px;
  }
  .ps-logo { width: 108px; height: auto; flex: none; margin-top: 2px; }
  .ps-title { flex: 1 1 auto; }
  .ps-title h1 { margin: 0; font-size: 15pt; letter-spacing: -.01em; }
  .ps-meta { margin-top: 3px; font-size: 8.5pt; color: #444; }
  .ps-sign { flex: none; width: 46mm; font-size: 8pt; color: #444; }
  .ps-sign div { border-bottom: .6pt solid #666; padding: 2px 0 12px; }
  .ps-sign div + div { margin-top: 6px; }

  .ps-h {
    display: flex; align-items: baseline; gap: 8px;
    margin: 16px 0 7px; font-size: 12pt; break-after: avoid;
    border-bottom: .8pt solid #000; padding-bottom: 4px;
  }
  .ps-h:first-of-type { margin-top: 0; }
  /* Outlined, not filled: browsers print backgrounds only when the user ticks
     "background graphics", and a white numeral on a dropped black disc would
     vanish. A border always prints. */
  .ps-n {
    flex: none; width: 16px; height: 16px; border-radius: 50%;
    border: .8pt solid #000; color: #000; font-weight: 700;
    font-size: 8pt; line-height: 15px; text-align: center;
  }
  .ps-h small { margin-left: auto; font-weight: 400; font-size: 8.5pt; color: #555; }
  .ps-h3 {
    margin: 11px 0 5px; font-size: 10pt; break-after: avoid;
    padding-left: 7px; border-left: 2.5pt solid #444;
  }

  /* Horizontal rules only. A full grid of hairlines is unreliable on paper:
     print pipelines snap 1px lines to the device grid, and the vertical ones
     land between pixels and disappear while the horizontal ones survive, which
     is what made the earlier grid look half-drawn. Rules are specified in pt
     and dark enough to render on any printer; columns are separated by space
     instead of lines. */
  .ps-tbl {
    width: 100%; border-collapse: collapse; margin-bottom: 8px;
    font-size: 9pt; break-inside: auto;
  }
  .ps-tbl thead th {
    padding: 4px 10px 4px 0;
    border-top: 1pt solid #000; border-bottom: .6pt solid #000;
    text-align: left; font-size: 8pt; font-weight: 700;
    text-transform: uppercase; letter-spacing: .04em;
  }
  .ps-tbl tbody th, .ps-tbl tbody td {
    padding: 4px 10px 4px 0; border-bottom: .5pt solid #8a8a8a;
    text-align: left; vertical-align: top;
  }
  .ps-tbl tbody tr:last-child > * { border-bottom: 1pt solid #000; }
  /* Tables built without a head still need an opening rule. */
  .ps-bare tbody tr:first-child > * { border-top: 1pt solid #000; }
  .ps-tbl thead th:last-child,
  .ps-tbl tbody th:last-child, .ps-tbl tbody td:last-child { padding-right: 0; }
  .ps-tbl tbody th { font-weight: 600; }
  .ps-tbl tbody tr { break-inside: avoid; }
  .ps-tbl tbody th small {
    display: block; font-weight: 400; font-size: 7.5pt; color: #555; margin-top: 1px;
  }
  /* A repeated head keeps a table that spans pages readable. */
  .ps-tbl thead { display: table-header-group; }
  .ps-num { text-align: right !important; font-variant-numeric: tabular-nums; white-space: nowrap; }
  .ps-url {
    display: block; margin-top: 1px; font-weight: 400; font-size: 7.5pt;
    color: #555 !important; text-decoration: none;
  }
  .ps-muted { color: #666; font-size: 9pt; }
  .ps-off th, .ps-off td { color: #777; }

  .ps-cond th:first-child { width: 40%; }
  .ps-calc th:first-child { width: 60%; }
  .ps-prod td.ps-num:first-child { width: 6mm; }
  .ps-prod tbody th { width: 31%; }
  .ps-prod tbody td.ps-num { width: 12mm; }
  .ps-note { font-size: 8pt; color: #333; }

  .ps-why { margin: 8px 0 10px; break-inside: avoid; }
  .ps-why h4 { margin: 0 0 4px; font-size: 9pt; }
  .ps-r-fail > * { background: #f0f0f0; }
  .ps-r-fail th::after { content: " ✗"; }
  .ps-r-pass th::after { content: " ✓"; }

  .ps-warn { margin: 0 0 8px; padding-left: 16px; font-size: 9pt; }
  .ps-warn li { margin-bottom: 2px; break-inside: avoid; }

  .ps-foot {
    margin-top: 16px; padding-top: 6px; border-top: .5pt solid #8a8a8a;
    font-size: 7.5pt; color: #666; word-break: break-all;
  }
}

/* The product lines a user account may work in: a short list of checkboxes,
   wrapped so a site with a dozen lines does not push the dialog wide. */
.linetick { display: flex; flex-wrap: wrap; gap: 6px 14px; margin-top: 6px; }
.linetick .tick {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 13px; padding: 5px 9px; border: 1px solid var(--line);
  border-radius: 8px; cursor: pointer;
}
.linetick .tick:has(input:disabled) { opacity: .5; cursor: default; }
.linetick .tick input { margin: 0; }

.searchbox {
  min-width: 280px; padding: 7px 11px; border: 1px solid var(--line);
  border-radius: 8px; background: var(--surface); color: var(--ink); font: inherit;
}
.searchbox:focus { outline: 2px solid var(--brand); outline-offset: 1px; }
