/* ════════════════════════════════════════════════════════════
   ARTUR'S LAB. APP
   Shell, components, screens, breakpoints. Written mobile-first:
   wider breakpoints only add.

   The feed borrows its shape from Instagram. One column, one
   post at a time, who → picture → actions → words, because that
   order is what people already know how to read. What it does
   not borrow is the palette or the type. The pin rail still sits
   above every image, and the colours still come off a board.

   Load order: tokens.css → base.css → app.css   ← this file last
   ════════════════════════════════════════════════════════════ */


/* ════════════════ 1. SHELL ════════════════ */

.topbar{
  position: sticky; top: 0; z-index: 60;
  height: var(--bar);
  background: var(--card);
  border-bottom: 1px solid var(--rule);
}
.topbar-in{
  display: flex; align-items: center; gap: .75rem;
  height: 100%; padding-inline: var(--gutter);
}

/* Wordmark. The mark is a 2×3 pad footprint. A header
   silkscreen, drawn in CSS. */
.brand{ display: flex; align-items: center; gap: .55rem; flex-shrink: 0; }
.brand-mark{
  display: grid; grid-template-columns: repeat(2, 5px); gap: 2px;
  padding: 3px; border: 1px solid var(--ink);
}
.brand-mark i{ width: 5px; height: 5px; background: var(--ink); }
.brand-mark i:nth-child(1){ background: var(--pad-lit); }
.brand-name{
  font-family: var(--display); font-weight: 700;
  font-size: .9375rem; letter-spacing: -.02em; white-space: nowrap;
}
.brand-name span{ color: var(--mask); }

.search{ position: relative; flex: 1; max-width: 380px; }
.search .input{
  padding-left: 2.1rem; min-height: 36px; padding-block: .35rem;
  background: var(--sunk); border-color: transparent; border-radius: 8px;
}
.search .input:focus{ background: var(--card); }
.search::before{
  content: "/"; position: absolute; left: .8rem; top: 50%;
  transform: translateY(-50%);
  font-family: var(--mono); font-size: var(--t-code); color: var(--ink-2);
}

.topacts{ display: flex; align-items: center; gap: .5rem; flex-shrink: 0; }
.topacts .btn .i{ width: 16px; height: 16px; }
.topme{ display: inline-flex; }

.shell{
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  padding-bottom: calc(var(--tabbar) + 1rem);
}
.main{ min-width: 0; padding: var(--gutter); }
.rail{ display: none; }


/* ── Icons ──────────────────────────────────────────────────
   One set, one grid, one stroke weight. Size is set by the
   thing holding them, never by the icon itself. */

.i{ width: 22px; height: 22px; flex-shrink: 0; }

.iconbtn{
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 40px; min-height: 40px;
  border-radius: 50%; color: var(--ink);
  transition: color .15s, transform .15s var(--ease), background .15s;
}
.iconbtn:hover{ background: var(--sunk); }
.iconbtn:active{ transform: scale(.9); }
.iconbtn.on-like{ color: var(--mask); }
.iconbtn.on-build{ color: var(--pad); }


/* ── Left rail (desktop) ────────────────────────────────────── */

.rail-in{ position: sticky; top: calc(var(--bar) + 1rem); padding: 1.25rem 0 1.25rem var(--gutter); }
.rail-group + .rail-group{ margin-top: 1.25rem; padding-top: 1rem; border-top: 1px solid var(--rule); }
.rail-hd{ padding: 0 .75rem .5rem; }
.rail a, .rail button.navitem{
  display: flex; align-items: center; gap: .7rem; width: 100%;
  padding: .55rem .75rem; border-radius: 8px;
  font-size: var(--t-sm); color: var(--ink-2);
  text-align: left;
}
.rail a:hover, .rail button.navitem:hover{ background: var(--sunk); color: var(--ink); }
.rail a.on{ background: var(--mask-lo); color: var(--mask); font-weight: 600; }
.rail a.on .i{ stroke-width: 2; }
.navitem .i{ width: 20px; height: 20px; }
.navitem-me{ line-height: 1.25; }
.navitem .count{
  margin-left: auto;
  font-family: var(--mono); font-size: var(--t-mono);
  background: var(--flag); color: var(--on-flag);
  padding: .1rem .35rem; border-radius: 99px;
}


/* ── Right index column (wide desktop) ──────────────────────── */

/* ── Mobile bottom nav ──────────────────────────────────────── */

.tabbar{
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
  display: flex;
  height: var(--tabbar);
  background: var(--card); border-top: 1px solid var(--rule);
  padding-bottom: env(safe-area-inset-bottom);
}
.tabbar a{
  flex: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .15rem;
  font-family: var(--mono); font-size: 9px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-2);
  position: relative;
}
.tabbar a .i{ width: 23px; height: 23px; }
.tabbar a.on{ color: var(--ink); }
.tabbar a.on .i{ stroke-width: 2.1; }
.tabbar a.on::before{
  content: ""; position: absolute; top: 0; left: 28%; right: 28%; height: 2px;
  background: var(--ink);
}
.tabbar .dot{
  position: absolute; top: 8px; right: 50%; margin-right: -16px;
  width: 6px; height: 6px; border-radius: 50%; background: var(--flag);
}


/* ════════════════ 2. AVATARS ════════════════
   The ring is the stories device, kept everywhere an account
   appears so one visual means one thing. Gold-to-green gradient
   for a maintainer, hairline grey for everyone else, so the
   person who approves submissions is identifiable in a thread
   without a label having to say so.
   ════════════════════════════════════════════ */

.ring{
  display: inline-grid; place-items: center; flex-shrink: 0;
  width: 34px; height: 34px; padding: 2px;
  border-radius: 50%; background: var(--ring-off);
}
.ring-admin{ background: var(--ring); }
.ring-sm{ width: 26px; height: 26px; padding: 1.5px; }
.ring-lg{ width: 92px; height: 92px; padding: 3px; }

.avatar{
  width: 100%; height: 100%;
  border-radius: 50%;
  display: grid; place-items: center;
  background: var(--card); color: var(--mask);
  box-shadow: inset 0 0 0 2px var(--card);
  font-family: var(--mono); font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .02em;
}
.ring-lg .avatar{ font-size: 26px; }
.ring-sm .avatar{ font-size: 9px; }


/* ════════════════ 3. BOARD STRIP ════════════════
   The stories row, doing a real job: every board with something
   published on it, most active first, one tap to filter.
   ═══════════════════════════════════════════════ */

.strip{
  display: flex; gap: .9rem;
  overflow-x: auto; scrollbar-width: none;
  padding: .25rem .1rem 1rem;
  border-bottom: 1px solid var(--rule);
  margin-bottom: 1rem;
}
.strip::-webkit-scrollbar{ display: none; }

.story{
  flex: 0 0 auto; width: 68px;
  display: flex; flex-direction: column; align-items: center; gap: .35rem;
}
.story-ring{
  display: grid; place-items: center;
  width: 60px; height: 60px; padding: 2.5px;
  border-radius: 50%; background: var(--ring-off);
  transition: transform .15s var(--ease);
}
.story.on .story-ring{ background: var(--ring); }
.story:hover .story-ring{ transform: scale(1.05); }
.story-face{
  display: grid; place-items: center;
  width: 100%; height: 100%; border-radius: 50%;
  background: var(--card); color: var(--ink-2);
  box-shadow: inset 0 0 0 2px var(--card);
}
.story.on .story-face{ color: var(--mask); }
.story-face .i{ width: 26px; height: 26px; }
.story-name{
  max-width: 100%;
  font-family: var(--mono); font-size: 10px; letter-spacing: .02em;
  color: var(--ink-2);
}
.story.on .story-name{ color: var(--ink); font-weight: 600; }
.story-n{ font-size: 10px; color: var(--ink-2); }


/* ════════════════ 4. SIGNATURE. THE PIN RAIL ════════════════
   A strip of 2.54mm header pads. Filled gold = a GPIO the
   project occupies. Outlined = free. It is decoration that is
   literally data: pin conflicts are the first thing anyone
   checks before building someone else's board, which is why it
   sits directly above the image rather than in a spec table.
   ══════════════════════════════════════════════════════════════ */

.pinrail{
  display: flex; gap: 2px;
  padding: 6px 10px;
  background: var(--sunk);
  border-block: 1px solid var(--rule);
  overflow: hidden;
}
.pinrail .pad{
  flex: 1; min-width: 3px; height: 8px;
  background: var(--card);
  border: 1px solid var(--rule-2);
  transition: background .2s var(--ease), border-color .2s var(--ease);
}
.pinrail .pad.used{ background: var(--pad-lit); border-color: var(--pad); }
.post:hover .pinrail .pad.used{ background: var(--pad); }

/* Full pinout on the detail page: same object, labelled. */
.pinout{ display: grid; grid-template-columns: repeat(auto-fill, minmax(58px, 1fr)); gap: 4px; }
.pinout .pin{
  border: 1px solid var(--rule-2); border-radius: var(--r);
  padding: .3rem .35rem;
  background: var(--card);
  font-family: var(--mono); font-size: 10px; line-height: 1.3;
}
.pinout .pin b{ display: block; font-weight: 600; color: var(--ink); }
.pinout .pin span{ display: block; color: var(--ink-2); }
.pinout .pin.used{ background: var(--pad-lo); border-color: var(--pad); }
.pinout .pin.used b{ color: var(--pad); }


/* ════════════════ 5. THE POST ════════════════ */

.feed{ max-width: var(--feed); margin-inline: auto; }
.feed-hd{
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; margin-bottom: .5rem;
}
.tabs{ display: flex; gap: .25rem; border-bottom: 1px solid var(--rule); margin-bottom: 1.25rem; }
.tabs button{
  padding: .55rem .8rem; margin-bottom: -1px;
  border-bottom: 2px solid transparent;
  font-family: var(--mono); font-size: var(--t-mono);
  letter-spacing: .07em; text-transform: uppercase; font-weight: 500;
  color: var(--ink-2);
}
.tabs button:hover{ color: var(--ink); }
.tabs button.on{ color: var(--mask); border-bottom-color: var(--mask); }

.post{
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: var(--r-card);
  overflow: hidden;
}
.post + .post{ margin-top: 1.5rem; }

.post-hd{ display: flex; align-items: center; gap: .6rem; padding: .6rem .75rem; }
.post-who{ display: flex; align-items: center; gap: .6rem; min-width: 0; }
.post-who-txt{ min-width: 0; line-height: 1.25; }
.post-who-txt b{ font-size: var(--t-sm); font-weight: 600; }
.post-who-txt .t-mono{ display: block; font-size: 10px; }
.post-hd .iconbtn{ min-width: 32px; min-height: 32px; color: var(--ink-2); }

.post-media{
  position: relative; display: block;
  aspect-ratio: 4 / 3;
  background-color: var(--sunk);
  background-image:
    var(--img, none),
    repeating-linear-gradient(90deg, var(--grid) 0 1px, transparent 1px 16px),
    repeating-linear-gradient(0deg,  var(--grid) 0 1px, transparent 1px 16px);
  background-size: cover, auto, auto;
  background-position: center, 0 0, 0 0;
  background-repeat: no-repeat, repeat, repeat;
}
/* Reference designator, bottom-right, the way a silkscreen
   labels a component. */
.desig{
  position: absolute; right: .55rem; bottom: .55rem;
  font-family: var(--mono); font-size: 10px; letter-spacing: .08em;
  color: var(--ink-2); background: var(--card);
  padding: .1rem .3rem; border: 1px solid var(--rule);
}

/* The double-tap heart. Nothing until it is asked for. */
.burst{
  position: absolute; inset: 0;
  display: grid; place-items: center;
  opacity: 0; pointer-events: none;
}
.burst .i{ width: 92px; height: 92px; color: var(--mask); filter: drop-shadow(0 2px 12px rgba(0,0,0,.35)); }
.burst.go{ animation: burst .85s var(--ease); }
@keyframes burst{
  0%   { opacity: 0; transform: scale(.4); }
  18%  { opacity: 1; transform: scale(1.08); }
  30%  { transform: scale(.96); }
  40%  { transform: scale(1); }
  75%  { opacity: 1; }
  100% { opacity: 0; transform: scale(1.1); }
}

.post-acts{
  display: flex; align-items: center; gap: .15rem;
  padding: .35rem .5rem 0;
}
.post-bd{ padding: .25rem .85rem 1rem; }
.post-count{ font-size: var(--t-sm); font-weight: 600; }
.post-caption{
  font-size: var(--t-sm); line-height: 1.55; margin-top: .3rem;
}
.post-caption > a > b{ font-weight: 600; }
.post-ttl{ color: var(--mask); }
.post-caption .t-dim{ margin-left: .15rem; }
.post-bd .card-tags{ margin: .6rem 0 .5rem; }
.post-more{
  display: inline-block;
  font-size: var(--t-sm); color: var(--ink-2);
}
.post-more:hover{ color: var(--ink); }
.post-when{ margin-top: .5rem; font-size: 10px; }

.card-tags{ display: flex; flex-wrap: wrap; gap: .35rem; }
button.tag{ cursor: pointer; }
button.tag:hover{ border-color: var(--ink); color: var(--ink); }

.byline{ display: flex; align-items: center; gap: .55rem; }

/* Like / build counts on the detail page. */
.act{
  display: inline-flex; align-items: center; gap: .35rem;
  min-height: 38px; padding: .25rem .6rem;
  border-radius: 8px;
  font-family: var(--mono); font-size: var(--t-mono);
  color: var(--ink-2); font-variant-numeric: tabular-nums;
}
.act .i{ width: 19px; height: 19px; }
.act:hover{ background: var(--sunk); color: var(--ink); }
.act.on-like{ color: var(--mask); }
.act.on-build{ color: var(--pad); }


/* ════════════════ 6. PROJECT DETAIL ════════════════ */

.detail{ max-width: 1080px; }
.detail-hero{
  aspect-ratio: 21 / 9;
  background-color: var(--sunk);
  background-image:
    var(--img, none),
    repeating-linear-gradient(90deg, var(--grid) 0 1px, transparent 1px 18px),
    repeating-linear-gradient(0deg,  var(--grid) 0 1px, transparent 1px 18px);
  background-size: cover, auto, auto;
  background-position: center, 0 0, 0 0;
  background-repeat: no-repeat, repeat, repeat;
  border: 1px solid var(--rule); border-radius: var(--r-card);
}
.detail-grid{ display: grid; gap: 1.5rem; margin-top: 1.5rem; }

.prose p{ margin-bottom: .9em; }
.prose p:last-child{ margin-bottom: 0; }
.prose h3{ margin: 1.4em 0 .5em; }
.prose ul{ list-style: disc; padding-left: 1.15rem; margin-bottom: .9em; }
.prose li{ margin-bottom: .25em; }
.prose code{
  font-family: var(--mono); font-size: .85em;
  background: var(--sunk); padding: .1em .3em; border-radius: 2px;
}

.panel{ background: var(--card); border: 1px solid var(--rule); border-radius: var(--r); }
.panel-hd{
  display: flex; align-items: center; justify-content: space-between; gap: .75rem;
  padding: .7rem .9rem; border-bottom: 1px solid var(--rule);
}
.panel-bd{ padding: .9rem; }
.panel + .panel{ margin-top: 1.25rem; }

/* Bill of materials. */
.bom{ width: 100%; border-collapse: collapse; font-size: var(--t-sm); }
.bom th{
  text-align: left; padding: .4rem .5rem;
  font-family: var(--mono); font-size: var(--t-mono);
  letter-spacing: .07em; text-transform: uppercase;
  color: var(--ink-2); font-weight: 500;
  border-bottom: 1px solid var(--rule-2);
}
.bom td{ padding: .5rem; border-bottom: 1px solid var(--rule); vertical-align: top; }
.bom tr:last-child td{ border-bottom: 0; }
.bom .qty{ font-family: var(--mono); font-variant-numeric: tabular-nums; width: 3rem; }
.bom .part{ font-family: var(--mono); font-size: var(--t-code); color: var(--ink-2); }

/* Spec list. */
.spec{ margin: 0; }
.spec > div{
  display: flex; justify-content: space-between; gap: 1rem;
  padding: .45rem 0; border-bottom: 1px solid var(--rule);
}
.spec > div:last-child{ border-bottom: 0; }
.spec dt{ font-family: var(--mono); font-size: var(--t-mono); letter-spacing: .07em; text-transform: uppercase; color: var(--ink-2); }
.spec dd{ margin: 0; font-family: var(--mono); font-size: var(--t-code); text-align: right; }


/* ════════════════ 7. COMMENTS ════════════════ */

.thread{ margin-top: 1.75rem; padding-top: 1.25rem; border-top: 1px solid var(--rule); }
.cmts{ margin-bottom: 1.25rem; }
.cmt{ display: flex; gap: .65rem; padding: .55rem 0; }
.cmt-txt{ font-size: var(--t-sm); line-height: 1.5; }
.cmt-txt b{ font-weight: 600; margin-right: .3rem; }
.cmt-when{ font-size: 10px; margin-top: .15rem; }

.cmtbox{
  display: flex; align-items: center; gap: .6rem;
  padding-top: .9rem; border-top: 1px solid var(--rule);
}
.cmtbox .input{
  border: 0; background: transparent; padding-inline: 0;
}
.cmtbox .input:focus{ outline: 0; }
.cmtbox-out{ justify-content: center; }


/* Walking between projects. Titles rather than bare arrows, so
   you know what you are moving to before you commit to it. */
.pager{
  display: grid; grid-template-columns: 1fr auto 1fr; gap: .5rem;
  align-items: stretch;
  margin-top: 2rem; padding-top: 1.25rem; border-top: 1px solid var(--rule);
}
.pg-btn{
  display: flex; align-items: center; gap: .5rem; min-width: 0;
  padding: .7rem .8rem;
  border: 1px solid var(--rule); border-radius: var(--r);
  background: var(--card); font-size: var(--t-sm);
}
.pg-btn:hover{ border-color: var(--mask); color: var(--mask); }
.pg-btn .i{ width: 17px; height: 17px; flex-shrink: 0; }
.pg-btn:last-child{ justify-content: flex-end; text-align: right; }
.pg-fwd{ display: inline-flex; transform: rotate(180deg); }
.pg-btn.is-off{ border-style: dashed; opacity: .4; }
.pg-at{
  display: grid; place-content: center; text-align: center;
  padding-inline: .5rem; line-height: 1.4; color: var(--ink-2);
}
.pg-at span{ font-size: 9px; }

@media (max-width: 599px){
  .pager{ grid-template-columns: 1fr 1fr; }
  .pg-at{ grid-column: 1 / -1; order: -1; padding-bottom: .3rem; }
}


/* ════════════════ 8. CODE VIEWER ════════════════ */

.code{ border: 1px solid var(--rule); border-radius: var(--r); overflow: hidden; }
.code-tabs{
  display: flex; gap: 0; overflow-x: auto;
  background: var(--term-2); border-bottom: 1px solid #000;
}
.code-tabs button{
  padding: .55rem .85rem; white-space: nowrap;
  font-family: var(--mono); font-size: var(--t-mono);
  color: var(--term-dim); border-bottom: 2px solid transparent;
}
.code-tabs button:hover{ color: var(--term-ink); }
.code-tabs button.on{ color: var(--term-ink); background: var(--term); border-bottom-color: var(--pad-lit); }
.code-body{
  background: var(--term); color: var(--term-ink);
  padding: .9rem 1rem; margin: 0;
  font-family: var(--mono); font-size: var(--t-code); line-height: 1.7;
  overflow-x: auto; max-height: 460px;
}
.code-body .ln{ color: var(--term-dim); user-select: none; display: inline-block; width: 2.5em; }
.code-foot{
  display: flex; align-items: center; justify-content: space-between; gap: .75rem;
  padding: .5rem .75rem; background: var(--term-2);
  font-family: var(--mono); font-size: var(--t-mono); color: var(--term-dim);
}
.code-foot button{ color: var(--term-dim); }
.code-foot button:hover{ color: var(--term-ink); }


/* ════════════════ 9. FLASH PANEL ════════════════ */

.flash{ border: 1px solid var(--rule-2); border-radius: var(--r); background: var(--card); }
.flash-hd{ padding: .9rem; border-bottom: 1px solid var(--rule); }
.flash-bd{ padding: .9rem; }
.flash-state{
  display: flex; align-items: flex-start; gap: .6rem;
  padding: .65rem .75rem; border-radius: var(--r);
  font-size: .8125rem; line-height: 1.5;
}
.flash-ok{ background: var(--mask-lo); color: var(--mask); }
.flash-no{ background: var(--flag-lo); color: var(--flag); }
.flash-log{
  margin-top: .75rem; padding: .7rem .8rem;
  background: var(--term); color: var(--term-ink); border-radius: var(--r);
  font-family: var(--mono); font-size: 11px; line-height: 1.75;
  max-height: 180px; overflow-y: auto;
}
.flash-log .dim{ color: var(--term-dim); }
.flash-log .ok{ color: #7FC99B; }


/* ════════════════ 10. SUBMIT FLOW ════════════════ */

.submit{ max-width: 720px; margin-inline: auto; }
.stepper{ display: flex; gap: 0; margin-bottom: 1.75rem; border-bottom: 1px solid var(--rule); }
.stepper .step{
  flex: 1; padding: .5rem .25rem .7rem; text-align: left;
  border-bottom: 2px solid transparent;
  font-family: var(--mono); font-size: var(--t-mono); letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-2);
}
.stepper .step b{ display: block; font-size: 15px; font-weight: 600; letter-spacing: 0; margin-bottom: .1rem; }
.stepper .step.on{ color: var(--mask); border-bottom-color: var(--mask); }
.stepper .step.done{ color: var(--ink); border-bottom-color: var(--rule-2); }

.chipset{ display: flex; flex-wrap: wrap; gap: .4rem; }
.chip{
  padding: .4rem .65rem;
  border: 1px solid var(--rule-2); border-radius: var(--r);
  background: var(--card);
  font-family: var(--mono); font-size: var(--t-mono);
  letter-spacing: .06em; text-transform: uppercase; color: var(--ink-2);
  min-height: 34px;
}
.chip:hover{ border-color: var(--ink); color: var(--ink); }
.chip[aria-pressed="true"]{ background: var(--mask); border-color: var(--mask); color: var(--on-mask); }

/* GPIO picker. The pin rail turned into an input. */
.pingrid{ display: grid; grid-template-columns: repeat(auto-fill, minmax(52px, 1fr)); gap: 4px; }
.pingrid button{
  padding: .35rem .2rem;
  border: 1px solid var(--rule-2); border-radius: var(--r);
  background: var(--card);
  font-family: var(--mono); font-size: 10px; color: var(--ink-2);
  min-height: 34px;
}
.pingrid button:hover{ border-color: var(--pad); }
.pingrid button[aria-pressed="true"]{ background: var(--pad-lo); border-color: var(--pad); color: var(--pad); font-weight: 600; }

.bomedit .bomrow{ display: grid; grid-template-columns: 3.5rem 1fr 1fr 2rem; gap: .4rem; margin-bottom: .4rem; }
.bomedit .bomrow .input{ padding: .4rem .5rem; font-size: .8125rem; }

.dropzone{
  border: 1px dashed var(--rule-2); border-radius: var(--r);
  background: var(--sunk);
  padding: 1.75rem 1rem; text-align: center;
}
.filelist li{
  display: flex; align-items: center; gap: .6rem;
  padding: .5rem .6rem; border: 1px solid var(--rule); border-radius: var(--r);
  background: var(--card); margin-top: .4rem;
  font-family: var(--mono); font-size: var(--t-code);
}
.filelist .sz{ margin-left: auto; color: var(--ink-2); font-size: var(--t-mono); }

.formnav{ display: flex; justify-content: space-between; gap: .75rem; margin-top: 1.75rem; padding-top: 1.25rem; border-top: 1px solid var(--rule); }


/* ════════════════ 10b. WIRING CANVAS ════════════════
   Built thumb-first. Every terminal carries a 21-unit invisible
   hit circle, the toolbar buttons clear 38px, and nothing needs
   hover to be discoverable.
   ════════════════════════════════════════════════════ */

/* The one thing that must be impossible to miss. */
.warn{
  position: fixed; left: 0; right: 0; top: 0; z-index: 400;
  display: flex; align-items: flex-start; gap: .75rem;
  padding: .7rem var(--gutter);
  background: var(--flag); color: var(--on-flag);
  font-size: var(--t-sm); line-height: 1.45;
}
.warn code{
  font-family: var(--mono); font-size: .9em;
  background: rgba(0,0,0,.14); padding: .05em .3em; border-radius: 2px;
}
.warn-x{
  flex-shrink: 0; width: 28px; height: 28px; border-radius: 50%;
  color: inherit; font-size: 18px; line-height: 1;
}
.warn-x:hover{ background: rgba(0,0,0,.14); }

/* Waiting for the far end of a wire: light up everything that
   can take it, so the next tap is obvious. */
.dg-empty{
  position: absolute; inset: auto 0 1rem; text-align: center;
  color: var(--ink-2); pointer-events: none;
}
.dg-empty .t-mono{ font-size: 10px; letter-spacing: .07em; text-transform: uppercase; }
.dg-svg.is-arming .dg-term:not(.is-hot) .dg-dot{
  stroke: var(--mask); stroke-width: 2.5; r: 7.5;
}
.dg-svg.is-arming .dg-term:not(.is-hot) .dg-tl{ fill: var(--mask); }
.dg-term.is-hot .dg-dot{ animation: dgpulse 1.4s ease-in-out infinite; }
@keyframes dgpulse{ 50%{ opacity: .45; } }

.dg{ border: 1px solid var(--rule-2); border-radius: var(--r-card); overflow: hidden; background: var(--card); }

.dg-bar{
  display: flex; align-items: center; gap: .75rem; flex-wrap: wrap;
  padding: .6rem .75rem; border-bottom: 1px solid var(--rule);
  background: var(--sunk);
}
.dg-tip{ flex: 1; min-width: 12rem; color: var(--ink-2); line-height: 1.4; }
.dg-tip b{ color: var(--mask); }
.dg-tools{ display: flex; gap: .35rem; align-items: center; }
.dg-zoom{
  display: inline-flex; align-items: center; gap: .2rem;
  border: 1px solid var(--rule-2); border-radius: var(--r);
  background: var(--card); padding: 2px;
}
.dg-zoom .btn{ border: 0; min-width: 34px; }
.dg-zoom b{
  min-width: 3.4rem; text-align: center;
  font-family: var(--mono); font-size: var(--t-mono); color: var(--ink-2);
}
.dg-tools .btn{ min-width: 42px; }

.dg-stage{
  position: relative;
  height: 60vh; min-height: 320px; max-height: 560px;
  background: var(--paper);
  touch-action: none;                 /* the canvas owns the gesture */
  overflow: hidden;
}
.dg-svg{ width: 100%; height: 100%; display: block; cursor: grab; }
.dg-svg:active{ cursor: grabbing; }
.dg-gridcell{ fill: var(--rule); }

/* Artwork inside a node. It must never eat the pointer. The box
   underneath is what you drag, and the dots are what you tap. */
.dg-art{ pointer-events: none; }

.boardrow .panel-bd{ gap: 1rem; }
.boardpic{
  width: 34px; height: 84px; object-fit: contain; flex-shrink: 0;
  border-radius: 3px;
}
.boardrow[disabled]{ opacity: .55; cursor: not-allowed; }

.dg-box{
  fill: var(--card); stroke: var(--rule-2); stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
}
.is-board /* Artwork inside a node. It must never eat the pointer. The box
   underneath is what you drag, and the dots are what you tap. */
.dg-art{ pointer-events: none; }

.boardrow .panel-bd{ gap: 1rem; }
.boardpic{
  width: 34px; height: 84px; object-fit: contain; flex-shrink: 0;
  border-radius: 3px;
}
.boardrow[disabled]{ opacity: .55; cursor: not-allowed; }

.dg-box{ fill: var(--mask-lo); stroke: var(--mask); }
.is-sel /* Artwork inside a node. It must never eat the pointer. The box
   underneath is what you drag, and the dots are what you tap. */
.dg-art{ pointer-events: none; }

.boardrow .panel-bd{ gap: 1rem; }
.boardpic{
  width: 34px; height: 84px; object-fit: contain; flex-shrink: 0;
  border-radius: 3px;
}
.boardrow[disabled]{ opacity: .55; cursor: not-allowed; }

.dg-box{ stroke: var(--mask); stroke-width: 3; }
.dg-node{ cursor: move; }
.dg-desig{
  font-family: var(--mono); font-size: 15px; font-weight: 600;
  fill: var(--ink);
}
.dg-name{ font-family: var(--body); font-size: 13px; fill: var(--ink-2); }

.dg-hit{ fill: transparent; }
.dg-dot{
  fill: var(--card); stroke: var(--rule-2); stroke-width: 1.5;
  vector-effect: non-scaling-stroke; pointer-events: none;
}
.dg-term.is-wired .dg-dot{ fill: var(--pad-lit); stroke: var(--pad); }
.dg-term.is-hot .dg-dot{ fill: var(--mask); stroke: var(--mask); r: 9; }
.dg-term{ cursor: pointer; }
.dg-tl{
  font-family: var(--mono); font-size: 11px; fill: var(--ink-2);
  pointer-events: none;
}
.dg-term.is-hot .dg-tl{ fill: var(--mask); font-weight: 600; }

.dg-wire{ fill: none; stroke-width: 2.5; vector-effect: non-scaling-stroke; }
.dg-sig{ stroke: var(--mask); }
.dg-pwr{ stroke: var(--pad); }
.dg-gnd{ stroke: var(--ink); }
.dg-grab{ fill: none; stroke: transparent; stroke-width: 22; cursor: pointer; }
.dg-wireg.is-sel .dg-wire{ stroke-dasharray: 7 5; stroke-width: 4; }

kbd{
  font-family: var(--mono); font-size: 9px;
  padding: .1em .35em; border-radius: 3px;
  background: rgba(255,255,255,.22); border: 1px solid rgba(255,255,255,.28);
}
/* Value entry sits in the selection bar. Typing works, and so do
   the chips, which is the only realistic way to set a resistance
   with a thumb. */
.dg-val{
  display: flex; align-items: center; gap: .3rem; flex-wrap: wrap;
  width: 100%; margin-top: .5rem;
}
.dg-val .input{ width: auto; min-width: 8rem; max-width: 11rem; padding: .35rem .5rem; }
.dg-val .chip{ min-height: 30px; padding: .25rem .5rem; }

.dg-sel{
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  padding: .6rem .75rem; border-top: 1px solid var(--rule);
  background: var(--mask-lo);
  font-size: var(--t-sm);
}

.dg-parts{ border-top: 1px solid var(--rule); padding: .75rem; }
.dg-cats{ display: flex; gap: .35rem; overflow-x: auto; padding-bottom: .6rem; scrollbar-width: none; }
.dg-cats::-webkit-scrollbar{ display: none; }
.dg-grid{ display: grid; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); gap: .4rem; }
.dg-part{
  display: flex; align-items: center; gap: .55rem;
  min-height: 54px; padding: .45rem .55rem;
  border: 1px solid var(--rule-2); border-radius: var(--r);
  background: var(--card); text-align: left;
}
.dg-part:hover{ border-color: var(--mask); background: var(--mask-lo); }
.dg-part-pic{ width: 30px; height: 30px; flex-shrink: 0; object-fit: contain; }
.dg-part-txt{ min-width: 0; line-height: 1.2; }
.dg-part b{ display: block; font-size: var(--t-sm); font-weight: 600; }
/* The terminal list is the useful half. It tells you what you are
   about to have to wire. Truncate rather than wrap the button. */
.dg-part .t-mono{
  display: block; font-size: 9px; letter-spacing: .04em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* The published drawing: same shapes, no handles. */
.dg-still svg, .media-dg svg{ width: 100%; height: 100%; display: block; }
.dg-still{ background: var(--paper); border-radius: var(--r); overflow: hidden; }
.dg-still svg{ max-height: 340px; }
.media-dg{ position: absolute; inset: 0; padding: 6%; }
.detail-hero.is-dg{ display: grid; place-items: center; padding: 1rem; background: var(--paper); }
.detail-hero.is-dg svg{ max-height: 100%; }

.rev-dg{ background: var(--paper); border: 1px solid var(--rule); border-radius: var(--r); }
.rev-dg svg{ max-height: 220px; }
.rev-shot{ width: 100%; border-radius: var(--r); }

.drop{ margin-top: 1.25rem; border-top: 1px solid var(--rule); padding-top: 1rem; }
.drop summary{
  cursor: pointer; min-height: 38px; display: flex; align-items: center;
  font-family: var(--mono); font-size: var(--t-mono);
  letter-spacing: .07em; text-transform: uppercase; color: var(--ink-2);
}
.drop summary:hover{ color: var(--ink); }
.pingrid button.is-risky{ opacity: .5; }

.gaps{
  padding: .8rem .9rem; margin-bottom: 1.25rem;
  border: 1px dashed var(--rule-2); border-radius: var(--r);
  background: var(--sunk);
}
.gaps ul{ margin-top: .4rem; }
.gaps li{ font-size: var(--t-sm); color: var(--ink-2); }
.gaps li::before{ content: "· "; }


/* ════════════════ 10c. PHOTOS ════════════════ */

.shots{ display: flex; gap: .5rem; flex-wrap: wrap; }
.shot{
  position: relative; width: 104px; height: 104px;
  border: 1px solid var(--rule-2); border-radius: var(--r); overflow: hidden;
}
.shot img{ width: 100%; height: 100%; object-fit: cover; }
.shot-tag{
  position: absolute; left: 0; bottom: 0;
  background: var(--mask); color: var(--on-mask); padding: .1rem .3rem;
  font-size: 9px; letter-spacing: .06em;
}
.shot-x{
  position: absolute; right: 2px; top: 2px;
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--scrim); color: #fff; font-size: 15px; line-height: 1;
}
.shot-add{
  display: grid; place-items: center; gap: .2rem;
  width: 104px; height: 104px;
  border: 1px dashed var(--rule-2); border-radius: var(--r);
  background: var(--sunk); color: var(--ink-2); cursor: pointer;
  font-size: 20px;
}
.shot-add:hover{ border-color: var(--mask); color: var(--mask); }
.shot-add .t-mono{ font-size: 10px; }

.gal{
  display: grid; grid-auto-flow: column; grid-auto-columns: 100%;
  gap: 4px;
  overflow-x: auto; scroll-snap-type: x mandatory;
  border-radius: var(--r-card); scrollbar-width: none;
}
.gal::-webkit-scrollbar{ display: none; }
.gal-item{ scroll-snap-align: center; margin: 0; }
.gal-item img{
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  border-radius: var(--r-card); background: var(--sunk);
}
.gal-hint{ margin-top: .4rem; text-align: center; }


/* ════════════════ 11. MODERATION QUEUE ════════════════ */

.queue{ max-width: 980px; }
.qitem{ background: var(--card); border: 1px solid var(--rule); border-radius: var(--r); margin-bottom: .75rem; }
.qitem.open{ border-color: var(--rule-2); }
.qhead{
  display: flex; align-items: center; gap: .75rem;
  width: 100%; padding: .8rem .9rem; text-align: left;
}
.qhead .grow{ min-width: 0; }
.qbody{ padding: 0 .9rem .9rem; border-top: 1px solid var(--rule); }
.qcheck{ display: flex; flex-wrap: wrap; gap: .35rem; margin: .75rem 0; }
.qacts{ display: flex; flex-wrap: wrap; gap: .5rem; padding-top: .75rem; border-top: 1px solid var(--rule); }

.empty{
  padding: 3rem 1.5rem; text-align: center;
  border: 1px dashed var(--rule-2); border-radius: var(--r-card);
  background: var(--sunk); color: var(--ink-2);
}


/* ════════════════ 12. PROFILE ════════════════
   Header, then a grid. Counts sit inline under the handle where
   they are read as one line, and the grid is the archive. The
   thing a profile is actually for.
   ═════════════════════════════════════════════ */

.profile{ max-width: 940px; margin-inline: auto; }
.pro{
  display: flex; gap: 1.5rem; align-items: flex-start;
  padding-bottom: 1.5rem; margin-bottom: 1.5rem;
  border-bottom: 1px solid var(--rule);
}
.pro-main{ min-width: 0; flex: 1; }
.pro-top{ display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; margin-bottom: .9rem; }
.pro-handle{
  font-family: var(--mono); font-size: 1.125rem; font-weight: 500;
  letter-spacing: .02em;
}
.pro-handle::before{ content: "@"; color: var(--ink-2); }
.pro-stats{ display: flex; gap: 1.5rem; flex-wrap: wrap; margin-bottom: .8rem; }
.pro-stats li{ font-size: var(--t-sm); color: var(--ink-2); }
.pro-stats b{ font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
.pro-name{ font-size: var(--t-sm); font-weight: 600; }
.pro .bio{ max-width: 56ch; color: var(--ink-2); font-size: var(--t-sm); margin-top: .2rem; }
.pro-meta{ margin-top: .35rem; }
.pro-sec{ margin: 1.5rem 0 .75rem; }

.grid3{ display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; }
.tilewrap{ position: relative; }
/* Owner controls sit over the tile. Always visible on touch,
   where there is no hover to reveal them. */
.tile-own{
  position: absolute; left: 4px; right: 4px; bottom: 4px;
  display: flex; gap: 4px; justify-content: center;
  opacity: 0; transition: opacity .12s var(--ease);
}
.tile-own .btn{ flex: 1; min-height: 30px; padding: .2rem .3rem; font-size: 9px; }
.tilewrap:hover .tile-own,
.tilewrap:focus-within .tile-own{ opacity: 1; }
@media (hover: none){ .tile-own{ opacity: 1; } }
.tile{
  position: relative; display: block;
  border: 1px solid var(--rule); border-radius: var(--r);
  overflow: hidden; background: var(--card);
}
.tile-face{
  position: relative; display: block;
  aspect-ratio: 1 / 1;
  background-color: var(--sunk);
  background-image:
    var(--img, none),
    repeating-linear-gradient(90deg, var(--grid) 0 1px, transparent 1px 14px),
    repeating-linear-gradient(0deg,  var(--grid) 0 1px, transparent 1px 14px);
  background-size: cover, auto, auto;
  background-position: center, 0 0, 0 0;
  background-repeat: no-repeat, repeat, repeat;
}
.tile-flag{ position: absolute; left: .4rem; top: .4rem; background: var(--card); }
.tile-over{
  position: absolute; inset: 0 0 auto;
  height: 100%;
  display: flex; align-items: center; justify-content: center; gap: 1.1rem;
  background: var(--scrim); color: #fff;
  opacity: 0; transition: opacity .15s var(--ease);
  font-size: var(--t-sm); font-weight: 600;
}
.tile-over span{ display: inline-flex; align-items: center; gap: .35rem; }
.tile-over .i{ width: 18px; height: 18px; }
.tile:hover .tile-over, .tile:focus-visible .tile-over{ opacity: 1; }
.tile-cap{
  display: block; padding: .4rem .5rem .35rem;
  font-size: 10px; color: var(--ink-2);
}
.tile .pinrail{ padding: 4px 6px; border-bottom: 0; }


/* Quiet, present, out of the way. Sits above the mobile tab bar
   rather than under it. */
.foot{
  padding: 2rem var(--gutter) calc(var(--tabbar) + 2rem);
  border-top: 1px solid var(--rule);
  text-align: center;
  font-size: .75rem; line-height: 1.7; color: var(--ink-2);
}
.foot p + p{ opacity: .8; }

@media (min-width: 900px){
  .foot{ padding-bottom: 2rem; }
}


/* ════════════════ 13. AUTH SHEET + TOAST ════════════════ */

/* Flex with margin:auto rather than place-items:center. Centred
   grid items cannot shrink past their content, so when a phone
   keyboard opens and halves the viewport, a grid-centred sheet
   gets pinned with its top edge off-screen and no way to scroll
   up to it. This version centres when there is room and scrolls
   when there is not. */
.modal-bg{
  position: fixed; inset: 0; z-index: 200;
  background: var(--scrim-2);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 1rem;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.modal{
  width: 100%; max-width: 400px;
  margin: auto;
  background: var(--card); border: 1px solid var(--rule-2); border-radius: var(--r-card);
  padding: 1.75rem 1.5rem 1.5rem;
}
/* The sheet holds a form; 16px stops iOS zooming the page in on
   focus, which is its own kind of "it jumped away from me". */
.modal .input{ font-size: 16px; }
.auth{ position: relative; }
.auth-x{
  position: absolute; right: .6rem; top: .5rem;
  width: 34px; height: 34px; border-radius: 50%;
  font-size: 20px; line-height: 1; color: var(--ink-2);
}
.auth-x:hover{ background: var(--sunk); color: var(--ink); }
.auth-brand{
  display: flex; align-items: center; justify-content: center; gap: .5rem;
  margin-bottom: 1.1rem;
}
.auth-brand .brand-name{ font-size: 1.0625rem; }
.auth-ttl{ text-align: center; }
.auth-sub{ text-align: center; margin: .35rem auto 1.1rem; max-width: 34ch; }

/* Segmented control. Two states, one width each. */
.seg{
  display: grid; grid-template-columns: 1fr 1fr; gap: 2px;
  padding: 3px; margin-bottom: 1.25rem;
  background: var(--sunk); border-radius: 8px;
}
.seg button{
  padding: .5rem .5rem; border-radius: 6px;
  font-family: var(--mono); font-size: var(--t-mono);
  letter-spacing: .06em; text-transform: uppercase; font-weight: 500;
  color: var(--ink-2);
}
.seg button.on{ background: var(--card); color: var(--ink); box-shadow: 0 1px 2px rgba(0,0,0,.12); }

.auth-err{
  margin-top: .9rem; padding: .55rem .7rem;
  background: var(--flag-lo); color: var(--flag);
  border-radius: var(--r); font-size: .8125rem; line-height: 1.45;
}
.auth-go{ width: 100%; margin-top: 1.25rem; }
.auth-foot{
  margin-top: 1.1rem; padding-top: 1rem;
  border-top: 1px solid var(--rule); text-align: center; color: var(--ink-2);
}
.auth-foot button{ color: var(--mask); font-weight: 600; }
.auth-foot button:hover{ text-decoration: underline; }

.toast{
  position: fixed; left: 50%; bottom: calc(var(--tabbar) + 1rem); z-index: 300;
  transform: translateX(-50%);
  background: var(--ink); color: var(--paper);
  padding: .7rem 1rem; border-radius: 99px;
  font-family: var(--mono); font-size: var(--t-mono); letter-spacing: .06em;
  max-width: calc(100vw - 2rem); text-align: center;
}


/* ════════════════ 14. SETTINGS ════════════════ */

.settings{ max-width: 620px; margin-inline: auto; }
.set{ margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid var(--rule); }
.set:first-of-type{ border-top: 0; }
.set-hd{ margin-bottom: 1rem; }

.set-pic{ display: flex; align-items: center; gap: 1.25rem; margin-bottom: 1.5rem; flex-wrap: wrap; }
.set-pic .btn{ cursor: pointer; }
.set-pic .btn .i{ width: 16px; height: 16px; }
.set-pic .hint{ margin-top: .5rem; }

.themepick{ display: grid; grid-template-columns: repeat(3, 1fr); gap: .5rem; }
.themeopt{
  display: flex; flex-direction: column; align-items: flex-start; gap: .2rem;
  padding: .85rem .75rem;
  border: 1px solid var(--rule-2); border-radius: var(--r);
  background: var(--card); color: var(--ink-2); text-align: left;
}
.themeopt .i{ margin-bottom: .3rem; }
.themeopt b{ color: var(--ink); font-size: var(--t-sm); }
.themeopt .t-mono{ font-size: 9px; }
.themeopt:hover{ border-color: var(--ink); }
.themeopt.on{ border-color: var(--mask); background: var(--mask-lo); color: var(--mask); }
.themeopt.on b{ color: var(--mask); }

.setrows{ border: 1px solid var(--rule); border-radius: var(--r); overflow: hidden; }
.setrow{
  display: flex; align-items: center; gap: .7rem; width: 100%;
  padding: .85rem .9rem; text-align: left;
  font-size: var(--t-sm); color: var(--ink);
  border-bottom: 1px solid var(--rule); background: var(--card);
}
.setrow:last-child{ border-bottom: 0; }
.setrow:hover{ background: var(--sunk); }
.setrow .i{ width: 19px; height: 19px; color: var(--ink-2); }
.setrow.is-danger{ color: var(--flag); }
.setrow.is-danger .i{ color: var(--flag); }

.pro-tabs{ margin-top: 1.5rem; }
.pro-tabs button{ display: inline-flex; align-items: center; gap: .4rem; }
.pro-tabs .i{ width: 15px; height: 15px; }


/* ════════════════ 15. FIRST RUN ════════════════ */

.tour{ max-width: 440px; text-align: left; }
.tour-n{ color: var(--ink-2); margin-bottom: .5rem; }
.tour-body{ margin-top: .75rem; color: var(--ink-2); font-size: var(--t-sm); line-height: 1.6; }
.tour-dots{ display: flex; gap: .35rem; margin: 1.5rem 0 1.25rem; }
.tour-dots span{ width: 6px; height: 6px; border-radius: 50%; background: var(--rule-2); }
.tour-dots span.on{ background: var(--mask); width: 18px; border-radius: 3px; }
.tour-nav{ display: flex; align-items: center; gap: .5rem; }

.who{ margin: 1.25rem 0; max-height: 40vh; overflow-y: auto; }
.who li{
  display: flex; align-items: center; gap: .65rem;
  padding: .5rem 0; border-bottom: 1px solid var(--rule);
  line-height: 1.25;
}
.who li:last-child{ border-bottom: 0; }
.who b{ font-size: var(--t-sm); }

.post-via{
  display: flex; align-items: center; gap: .35rem;
  padding: .5rem .75rem .1rem; color: var(--ink-2);
}
.post-via .i{ width: 14px; height: 14px; }
.post-via a{ color: var(--ink); font-weight: 600; }

.iconbtn.on-save{ color: var(--ink); }
.iconbtn.on-repost{ color: var(--mask); }
.avatar-img{ object-fit: cover; }

@media (max-width: 599px){
  .settings{ padding-inline: var(--gutter); }
  .themepick{ grid-template-columns: 1fr; }
  .themeopt{ flex-direction: row; align-items: center; gap: .6rem; }
  .themeopt .i{ margin-bottom: 0; }
  .themeopt .t-mono{ margin-left: auto; }
}


/* ════════════════════════════════════════════════════════════
   BREAKPOINTS, tested at 375 / 768 / 1024 / 1440
   ════════════════════════════════════════════════════════════ */

@media (max-width: 439px){
  .brand-name{ display: none; }
}

@media (max-width: 599px){
  /* Only the primary action survives the top bar on a phone.
     The rest of the nav is already at the bottom of the screen. */
  .topacts .btn:not(.btn-primary){ display: none; }
  .topbar-in{ gap: .5rem; }

  /* Full-bleed posts, the way a phone feed reads. */
  .main{ padding-inline: 0; }
  .feed-hd, .tabs, .strip{ padding-inline: var(--gutter); }
  .strip{ margin-inline: 0; }
  .post{ border-radius: 0; border-inline: 0; }
  .profile, .submit, .queue, .detail{ padding-inline: var(--gutter); }
  .pro{ gap: 1rem; }
  .ring-lg{ width: 74px; height: 74px; }
  .ring-lg .avatar{ font-size: 21px; }
  .pro-stats{ gap: 1.1rem; }

  /* The canvas gets the screen. Below it, the parts drawer
     scrolls horizontally rather than stacking six rows deep. */
  .dg{ border-radius: 0; border-inline: 0; margin-inline: calc(var(--gutter) * -1); }
  .dg-stage{ height: 56vh; min-height: 300px; }
  .dg-grid{
    display: flex; gap: .4rem; overflow-x: auto;
    padding-bottom: .3rem; scrollbar-width: none;
  }
  .dg-grid::-webkit-scrollbar{ display: none; }
  .dg-part{ flex: 0 0 auto; min-width: 158px; }
  .dg-tip{ min-width: 100%; order: 2; }
  .dg-tools{ width: 100%; }
  .dg-tools .btn{ flex: 1; }

  /* Five steps do not fit across a phone. Let them scroll. */
  .stepper{ overflow-x: auto; scrollbar-width: none; }
  .stepper::-webkit-scrollbar{ display: none; }
  .stepper .step{ flex: 0 0 auto; min-width: 5.5rem; }

  .bomedit .bomrow{ grid-template-columns: 3rem 1fr 2rem; }
  .bomedit .bomrow .input:nth-child(3){ grid-column: 1 / -1; }
}

@media (min-width: 640px){
  .detail-grid{ grid-template-columns: 1fr; }
}

/* ── ≥ 900px: left rail replaces the bottom tab bar ─────────── */
@media (min-width: 900px){
  .shell{ grid-template-columns: var(--rail) minmax(0, 1fr); padding-bottom: 2rem; }
  .rail{ display: block; }
  .tabbar{ display: none; }
  .main{ padding: 1.5rem var(--gutter); border-left: 1px solid var(--rule); min-height: calc(100vh - var(--bar)); }
  .toast{ bottom: 1.5rem; }
  .detail-grid{ grid-template-columns: minmax(0, 1.65fr) minmax(260px, 1fr); }
}

@media (min-width: 1240px){
  .shell{ max-width: 1180px; margin-inline: auto; }
}
