/* ================================================================
   AnabhiDev-LAB — AnabhiDev Engineering Lab
   HTML · CSS · Vanilla JS · Cloudflare Pages
   Development · Anabhi Dev
   Version   : 1.3
   Generated : 5 September 2026, 11:40:00
   ----------------------------------------------------------------
   Page-level layouts: hero, registry filters, timeline, insights,
   project detail, notes & experiments.
   ================================================================ */

/* ══════════════════ HOME HERO ══════════════════ */
.hero{
  display:grid;grid-template-columns:1.06fr .94fr;gap:clamp(30px,5vw,68px);align-items:center;
  padding:clamp(52px,7vw,100px) 0 clamp(52px,7vw,92px);
}
@media(max-width:920px){ .hero{grid-template-columns:1fr;gap:42px} .hero-art{order:-1} }

.sub{
  font-family:'Bricolage Grotesque',sans-serif;font-weight:400;
  font-size:clamp(16px,1.7vw,21px);color:var(--muted);letter-spacing:-.01em;margin-bottom:26px;
}
.lede{
  font-size:16px;line-height:1.8;color:var(--muted);
  margin-bottom:34px;padding-left:18px;border-left:2px solid var(--accent);
}
.lede b{color:var(--ink);font-weight:600}

/* Hero art — a terminal-style panel; the Lab's own visual signature */
.term{
  border:1px solid var(--edge);border-radius:var(--r-lg);overflow:hidden;
  background:var(--surface);box-shadow:0 20px 45px rgba(0,0,0,.18);
}
.term-bar{display:flex;align-items:center;gap:7px;padding:11px 14px;border-bottom:1px solid var(--line)}
.term-bar i{width:7px;height:7px;border-radius:50%;background:var(--edge);opacity:.6;display:block}
.term-title{
  margin-left:8px;font-size:11px;color:var(--muted);
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
}
.term-body{padding:clamp(18px,2.4vw,26px);display:grid;gap:14px}
.term-row{display:grid;grid-template-columns:auto 1fr auto;gap:14px;align-items:center;font-size:13.5px}
.term-row + .term-row{padding-top:14px;border-top:1px solid var(--line)}
.term-k{
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:11.5px;color:var(--accent);letter-spacing:.04em;
}
.term-v{color:var(--muted)}
.term-n{font-family:'Bricolage Grotesque',sans-serif;font-weight:700;font-size:20px;letter-spacing:-.01em;color:var(--ink)}

/* ── Hero registry slider ──
   Rotates the featured records. Chosen over a photo slider because the Lab has
   no images of its own; stock photography would be decoration pretending to be
   evidence. Everything here comes from data/projects.json. */
.term-dots{display:flex;gap:2px;margin-left:auto}
.tdot{
  width:24px;height:24px;padding:0;border:0;background:transparent;cursor:pointer;
  display:grid;place-items:center;border-radius:50%;
}
.tdot::before{
  content:'';width:6px;height:6px;border-radius:50%;background:var(--edge);opacity:.5;
  transition:opacity .25s var(--ease),background .25s var(--ease),transform .25s var(--ease);
}
.tdot:hover::before{opacity:1}
.tdot[aria-current="true"]::before{background:var(--accent);opacity:1;transform:scale(1.25)}

/* Every slide sits in the SAME grid cell, so the panel is always as tall as its
   tallest slide and never resizes mid-rotation — CLS stays at zero.
   visibility (not display:none) does the hiding: it keeps the box for sizing
   while removing the slide from the tab order and the accessibility tree, so a
   keyboard user can never land on a link they cannot see. */
.hslides{display:grid}
.hslide{
  grid-area:1/1;visibility:hidden;opacity:0;
  transition:opacity .45s var(--ease),visibility 0s linear .45s;
}
.hslide.on{visibility:visible;opacity:1;transition:opacity .45s var(--ease),visibility 0s}
.hslide-meta{display:flex;flex-wrap:wrap;gap:6px 12px;align-items:baseline;margin-bottom:14px}
.hslide-num{
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:11.5px;color:var(--accent);letter-spacing:.04em;
}
.hslide-cat{font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.hslide-name{
  font-family:'Bricolage Grotesque',sans-serif;font-weight:700;
  font-size:clamp(21px,2.3vw,27px);line-height:1.18;letter-spacing:-.02em;color:var(--ink);
}
.hslide-note{font-size:14px;color:var(--muted);margin-top:10px;opacity:.85}
/* Tags are the one narrative field already filled in for every featured record,
   so they carry the panel while descriptions are still empty. Reuses .chips. */
.hslide-tags{margin-top:15px}
.hslide-link{
  display:inline-block;margin-top:20px;padding-bottom:3px;
  font-family:'Bricolage Grotesque',sans-serif;font-weight:600;font-size:13px;
  color:var(--accent);text-decoration:none;border-bottom:1px solid var(--edge);
  transition:border-color .2s var(--ease);
}
.hslide-link:hover{border-bottom-color:var(--accent)}
@media(prefers-reduced-motion:reduce){
  .hslide,.hslide.on{transition:none}
}

/* ══════════════════ INNER PAGE HERO ══════════════════ */
.page-hero{padding:clamp(44px,6vw,76px) 0 clamp(32px,4vw,48px)}
.page-hero h1{font-size:clamp(32px,4.4vw,58px)}
.page-hero .lede{max-width:64ch}

/* ══════════════════ REGISTRY FILTERS ══════════════════ */
.filters{
  display:grid;grid-template-columns:1.4fr repeat(4,1fr);gap:12px;align-items:end;
  padding:20px 0 24px;border-bottom:1px solid var(--line);margin-bottom:28px;
}
.field{display:flex;flex-direction:column;gap:7px;min-width:0}
.field label{
  font-family:'Bricolage Grotesque',sans-serif;font-weight:600;font-size:10px;
  letter-spacing:.14em;text-transform:uppercase;color:var(--muted);
}
.field input,.field select{
  width:100%;font-family:inherit;font-size:14px;color:var(--ink);
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-md);
  padding:11px 13px;min-height:44px;transition:border-color .2s var(--ease);
}
.field input:hover,.field select:hover{border-color:var(--edge)}
.field input::placeholder{color:var(--muted);opacity:.8}
.field select{cursor:pointer;appearance:none;background-image:none;padding-right:34px}
.field.has-caret{position:relative}
.field.has-caret::after{
  content:'';position:absolute;right:14px;bottom:19px;width:7px;height:7px;pointer-events:none;
  border-right:1.5px solid var(--muted);border-bottom:1.5px solid var(--muted);transform:rotate(45deg);
}

.filter-toggle{display:none}
.filter-bar-top{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;margin-bottom:8px}
.result-count{font-size:13px;color:var(--muted)}
.result-count b{color:var(--ink);font-weight:600}

@media(max-width:1080px){ .filters{grid-template-columns:1fr 1fr 1fr} }
@media(max-width:760px){
  .filters{grid-template-columns:1fr;gap:14px;padding:18px;border:1px solid var(--line);border-radius:var(--r-lg)}
  .filters[hidden]{display:none}
  .filter-toggle{display:inline-flex}
}

.view-switch{display:flex;border:1px solid var(--edge);border-radius:var(--r-sm);overflow:hidden}
.view-switch button{
  font-family:'Bricolage Grotesque',sans-serif;font-weight:600;font-size:11px;letter-spacing:.08em;
  text-transform:uppercase;padding:9px 13px;background:transparent;color:var(--muted);
  border:0;cursor:pointer;min-height:44px;
}
.view-switch button[aria-pressed="true"]{background:var(--accent);color:var(--accent-ink)}

/* ══════════════════ TIMELINE ══════════════════ */
.tl-group{margin-bottom:clamp(32px,4vw,52px)}
.tl-year{
  display:flex;align-items:baseline;gap:16px;padding-bottom:14px;
  border-bottom:1px solid var(--edge);margin-bottom:6px;
}
.tl-year h2{font-size:clamp(26px,3vw,38px);margin-bottom:0}
.tl-year .count{font-size:12px;letter-spacing:.13em;text-transform:uppercase;color:var(--muted)}
.tl-month{padding:22px 0 4px}
.tl-month h3{
  font-family:'Bricolage Grotesque',sans-serif;font-weight:600;font-size:11px;
  letter-spacing:.18em;text-transform:uppercase;color:var(--accent);margin-bottom:12px;
}

/* ══════════════════ INSIGHTS ══════════════════ */
.bars{display:grid;gap:14px}
.bar-row{display:grid;grid-template-columns:minmax(120px,190px) 1fr auto;gap:14px;align-items:center}
.bar-label{font-size:13.5px;color:var(--muted)}
.bar-track{height:9px;border-radius:5px;background:var(--soft);overflow:hidden;min-width:0}
/* display:block is REQUIRED, not decoration. .bar-fill is a <span>, and width
   and height are ignored on an inline box — without this the fill collapses to
   nothing and every bar looks identically full. .bar-track escapes the same bug
   only because it is a grid item of .bar-row, which blockifies it. */
.bar-fill{display:block;height:100%;border-radius:5px;background:var(--accent);transition:width .7s var(--ease)}
.bar-val{
  font-family:'Bricolage Grotesque',sans-serif;font-weight:700;font-size:14px;
  min-width:2.5ch;text-align:right;
}
a.bar-row{text-decoration:none;color:inherit;padding:4px 6px;margin:-4px -6px;border-radius:var(--r-sm);transition:background .15s}
a.bar-row:hover{background:var(--soft)}
a.bar-row:hover .bar-label{color:var(--ink)}
a.bar-row:hover .bar-val{color:var(--accent)}
@media(max-width:620px){
  .bar-row{grid-template-columns:1fr auto;row-gap:7px}
  .bar-track{grid-column:1 / -1}
}

.insight-note{
  border-left:2px solid var(--accent);padding-left:18px;margin-top:26px;
  font-size:15px;color:var(--muted);
}

/* ══════════════════ CATEGORY GRID ══════════════════ */
/* 10 categories. Only column counts that divide 10 are used (5 / 2 / 1), which
   is why 4 and 3 are skipped entirely — both would leave holes in the last row. */
.cat-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:16px}
@media(max-width:1100px){.cat-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:560px){.cat-grid{grid-template-columns:1fr}}
.cat-card{
  display:block;border:1px solid var(--line);border-radius:var(--r-md);padding:20px;
  text-decoration:none;color:inherit;transition:border-color .2s var(--ease);
}
.cat-card:hover,.cat-card:focus-visible{border-color:var(--accent)}
/* Both are <span>. Unlike .bar-val or .jmark they are NOT grid items — .cat-card
   is a plain block — so nothing blockifies them automatically. Left inline, the
   count and the name render glued together on one line and margin-top is
   silently ignored ("17Web Applications"). display:block is what separates them. */
.cat-card .n{display:block;font-family:'Bricolage Grotesque',sans-serif;font-weight:700;font-size:26px;line-height:1;color:var(--accent)}
.cat-card .t{display:block;font-family:'Bricolage Grotesque',sans-serif;font-weight:600;font-size:15px;margin-top:12px;letter-spacing:-.01em}

/* ══════════════════ PROJECT DETAIL ══════════════════ */
.detail-head{padding:clamp(36px,5vw,64px) 0 clamp(24px,3vw,36px)}
.crumb{font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin-bottom:20px}
.crumb a{color:var(--muted);text-decoration:none;border-bottom:1px solid transparent}
.crumb a:hover{color:var(--accent);border-bottom-color:var(--accent)}

.snapshot{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:1px;background:var(--line);border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden}
.snap{background:var(--bg);padding:18px}
.snap-l{font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted);margin-bottom:8px}
.snap-v{font-family:'Bricolage Grotesque',sans-serif;font-weight:600;font-size:15px;letter-spacing:-.01em}

.detail-body{display:grid;grid-template-columns:1fr;gap:clamp(28px,4vw,44px)}
.dsec{padding-top:clamp(26px,3vw,38px);border-top:1px solid var(--line)}
.dsec h2{font-size:clamp(20px,2.3vw,27px);margin-bottom:14px}
.dsec p{color:var(--muted);font-size:15.5px}

/* Journey stepper — the Lab's defining feature */
.journey{display:grid;gap:0;margin-top:6px}
.jstep{display:grid;grid-template-columns:auto 1fr;gap:18px;padding-bottom:24px;position:relative}
.jstep:last-child{padding-bottom:0}
.jmark{
  width:13px;height:13px;border-radius:50%;border:2px solid var(--edge);
  background:var(--bg);margin-top:5px;position:relative;z-index:1;
}
.jstep.done .jmark{background:var(--accent);border-color:var(--accent)}
.jstep:not(:last-child)::before{
  content:'';position:absolute;left:6px;top:20px;bottom:0;width:1px;background:var(--line);
}
.jstep h3{font-family:'Bricolage Grotesque',sans-serif;font-weight:600;font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--accent);margin-bottom:6px}
.jstep p{color:var(--muted);font-size:15px}

/* ══════════════════ NOTES & EXPERIMENTS ══════════════════ */
/* 6 notes. 3 / 2 / 1 columns all divide 6 exactly, so every row stays full.
   This grid used to be auto-fill, which produced 5 columns and left a single
   card stranded alone on the second row. */
.note-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
@media(max-width:1000px){.note-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:620px){.note-grid{grid-template-columns:1fr}}
.note{border:1px solid var(--line);border-radius:var(--r-lg);padding:22px;background:var(--surface)}
.note .k{font-family:'Bricolage Grotesque',sans-serif;font-weight:600;font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--accent);margin-bottom:11px;display:block}
.note h3{font-size:17px;margin-bottom:9px}
.note p{font-size:14.5px;color:var(--muted)}

.tmpl{display:grid;gap:0;border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden}
.tmpl-row{display:grid;grid-template-columns:minmax(140px,220px) 1fr;gap:0;border-bottom:1px solid var(--line)}
.tmpl-row:last-child{border-bottom:0}
.tmpl-k{
  padding:14px 18px;background:var(--soft);
  font-family:'Bricolage Grotesque',sans-serif;font-weight:600;font-size:11px;
  letter-spacing:.14em;text-transform:uppercase;color:var(--accent);
}
.tmpl-v{padding:14px 18px;color:var(--muted);font-size:14.5px}
@media(max-width:620px){ .tmpl-row{grid-template-columns:1fr} .tmpl-k{padding-bottom:4px;background:transparent} }

/* ══════════════════ ABOUT / STATEMENT ══════════════════ */
.split{display:grid;grid-template-columns:.9fr 1.1fr;gap:clamp(32px,5vw,72px);align-items:start}
@media(max-width:900px){.split{grid-template-columns:1fr;gap:40px}}
.about-p{color:var(--muted);font-size:16px;margin-bottom:16px}
.about-p b{color:var(--ink);font-weight:600}
.pull{
  margin-top:24px;padding-left:20px;border-left:2px solid var(--accent);
  font-family:'Bricolage Grotesque',sans-serif;font-size:17px;line-height:1.6;color:var(--ink);
}

.cta{text-align:center;padding:clamp(58px,7.5vw,104px) 0;scroll-margin-top:calc(var(--header-h) + 16px)}
.cta h2{margin-inline:auto;max-width:16ch}
.cta .sec-p{margin-inline:auto;margin-bottom:32px}
.cta .btns{justify-content:center}

/* ══════════════════ QUICK PILLS (REGISTRY) ══════════════════ */
.quick-pills{
  display:flex;align-items:center;gap:8px;overflow-x:auto;padding:12px 0 16px;
  margin-bottom:6px;-webkit-overflow-scrolling:touch;scrollbar-width:none;
}
.quick-pills::-webkit-scrollbar{display:none}
.quick-pill{
  font-family:'Bricolage Grotesque',sans-serif;font-weight:600;font-size:12px;letter-spacing:.03em;
  white-space:nowrap;padding:8px 14px;border-radius:20px;
  background:rgba(232,220,200,.06);border:1px solid rgba(232,220,200,.14);
  color:var(--muted);cursor:pointer;transition:all .18s var(--ease);line-height:1;min-height:36px;
}
.quick-pill:hover{background:rgba(201,169,106,.15);border-color:var(--edge);color:var(--ink)}
.quick-pill.is-active{background:var(--accent);color:var(--accent-ink);border-color:var(--accent)}

/* ══════════════════ VELOCITY CHART (INSIGHTS) ══════════════════ */
.velocity-chart-wrap{
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-md);
  padding:clamp(20px,3vw,32px);margin-bottom:24px;
}
.velocity-chart-head{
  display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;
}
.velocity-chart-title{font-family:'Bricolage Grotesque',sans-serif;font-weight:600;font-size:15px;color:var(--ink)}
.velocity-chart-sub{font-size:12px;color:var(--muted)}
.velocity-svg{width:100%;height:auto;max-height:220px;overflow:visible}
.velocity-bar-rect{fill:var(--accent);transition:fill .2s,opacity .2s;cursor:pointer;rx:4;ry:4}
.velocity-bar-rect:hover{fill:var(--gold-bright,#e5c382);opacity:.9}
.velocity-text-val{fill:var(--ink);font-family:'Bricolage Grotesque',sans-serif;font-weight:700;font-size:13px;text-anchor:middle}
.velocity-text-lbl{fill:var(--muted);font-family:'Bricolage Grotesque',sans-serif;font-weight:600;font-size:11px;text-anchor:middle}

/* ══════════════════ DETAIL ACTIONS ══════════════════ */
.detail-actions{display:flex;flex-wrap:wrap;gap:12px;align-items:center;margin-top:24px}
.detail-actions .btn-p,.detail-actions .btn-g{cursor:pointer;display:inline-flex;align-items:center;padding:10px 18px;font-size:13px;line-height:1.2}
.detail-actions svg{margin-right:7px;flex-shrink:0}

/* ══════════════════ PRINT FACT SHEET ══════════════════ */
@media print {
  .nav-outer, .foot, .cmd-overlay, .quick-pills, .detail-actions, #cmd-palette-btn, .cta { display: none !important; }
  body, .band-dark, .band-light { background: #fff !important; color: #111 !important; }
  main { margin-top: 0 !important; }
  .detail-head { padding: 16px 0 !important; }
  .snapshot { border: 1px solid #ccc !important; background: #eee !important; }
  .snap { background: #fff !important; color: #111 !important; border: 1px solid #ddd !important; }
  .snap-l { color: #666 !important; }
  .snap-v { color: #111 !important; }
  .dsec { border-top: 1px solid #ddd !important; padding-top: 14px !important; page-break-inside: avoid; }
  .dsec h2 { color: #111 !important; }
  .dsec p { color: #333 !important; }
  .chip { border: 1px solid #ccc !important; color: #333 !important; }
  .jmark { border-color: #333 !important; background: #fff !important; }
  .jstep.done .jmark { background: #333 !important; }
  .jstep h3 { color: #111 !important; }
  .jstep p { color: #444 !important; }
}

/* ══════════════════ 404 ══════════════════ */
.nf{
  min-height:calc(100vh - var(--header-h));   /* fallback */
  min-height:calc(100dvh - var(--header-h));
  display:grid;place-items:center;text-align:center;padding:60px 0;
}
.nf .code{font-family:'Bricolage Grotesque',sans-serif;font-weight:700;font-size:clamp(64px,12vw,140px);line-height:1;color:var(--accent);letter-spacing:-.03em}
