/* ============================================================
   abdrx portfolio — shared styles + theme system
   Two themes via [data-theme]. Amber accent stays; neutrals flip.

   Motion policy (audited): every hover/click transform lives inside
   an `@media (prefers-reduced-motion: no-preference)` block. Base
   rules always set the correct *end state* (color/opacity/position)
   with no animated property, so reduced-motion users still get the
   state change — just instantly, with zero simulated motion. Opacity
   fades are the one exception left always-on, since a plain fade is
   the accessible fallback, not something to strip further.
   ============================================================ */

/* ---- dark (default) ---- */
:root{
  --ink:#0C0E12;
  --panel:#14171D;
  --panel-2:#1A1E26;
  --line:#262B34;
  --line-2:#333A45;
  --text:#EAE8E3;
  --muted:#8B93A0;
  --muted-2:#646B77;
  --accent:#EFB247;        /* fills, shapes, underlines */
  --accent-text:#EFB247;   /* accent used as readable text */
  --btn-ink:#1c1405;       /* text on the amber button */
  --ok:#5BB98B;
  --tag-bg:#1A1E26;

  --glow1:rgba(239,178,71,.10);
  --glow2:rgba(90,120,160,.06);
  --grid:rgba(255,255,255,.018);

  --display:'Space Grotesk', system-ui, sans-serif;
  --body:'Inter', system-ui, sans-serif;
  --mono:'JetBrains Mono', ui-monospace, monospace;
  --maxw:1080px;

  --ease-settled:cubic-bezier(.16,.84,.28,1);
}

/* ---- light ---- */
[data-theme="light"]{
  --ink:#F6F4EE;
  --panel:#FFFFFF;
  --panel-2:#F1EEE6;
  --line:#E7E3D9;
  --line-2:#D8D3C6;
  --text:#1B1E24;
  --muted:#5D6470;
  --muted-2:#8A909B;
  --accent:#DE9E28;
  --accent-text:#9A6712;
  --btn-ink:#241a06;
  --ok:#2E9E6B;
  --tag-bg:#F1EEE6;

  --glow1:rgba(224,163,46,.14);
  --glow2:rgba(120,140,180,.05);
  --grid:rgba(20,20,30,.035);
}

*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

body{
  background:var(--ink);
  color:var(--text);
  font-family:var(--body);
  font-size:16px;line-height:1.6;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;position:relative;
  transition:background .3s ease, color .3s ease;
}

/* soft, temporary cross-fade applied to (almost) everything during a
   theme switch, so flipping data-theme never reads as a hard flash.
   The JS toggle adds this class for ~500ms around the attribute change. */
html.theme-transition,
html.theme-transition *{
  transition:background-color .45s ease, border-color .45s ease, color .45s ease, fill .45s ease, box-shadow .45s ease !important;
}
body::before{
  content:"";position:fixed;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(680px 420px at 8% -5%, var(--glow1), transparent 60%),
    radial-gradient(560px 400px at 100% 0%, var(--glow2), transparent 55%);
}
body::after{
  content:"";position:fixed;inset:0;z-index:0;pointer-events:none;
  background-image:
    linear-gradient(var(--grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid) 1px, transparent 1px);
  background-size:44px 44px;
  -webkit-mask-image:radial-gradient(circle at 50% 30%, #000 0%, transparent 80%);
  mask-image:radial-gradient(circle at 50% 30%, #000 0%, transparent 80%);
}

.wrap{position:relative;z-index:1;max-width:var(--maxw);margin:0 auto;padding:0 24px}

a{color:inherit;text-decoration:none}
a:focus-visible,button:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:6px}

.mono{font-family:var(--mono);font-weight:400}
.eyebrow{
  font-family:var(--mono);font-size:12.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted);
  display:flex;align-items:center;gap:10px;
}
.eyebrow::before{content:"";width:22px;height:1px;background:var(--accent)}

/* ---------- scroll progress ---------- */
/* a full-width hairline fixed to the very top of the viewport. Native
   CSS scroll-driven animation where supported (zero scroll-listener
   cost); the JS in site.js is a rAF-throttled fallback everywhere else. */
.scroll-progress{position:fixed;top:0;left:0;right:0;height:3px;z-index:50;pointer-events:none}
.scroll-progress .bar{display:block;height:100%;width:100%;transform-origin:0 50%;transform:scaleX(0);background:var(--accent-text)}
@supports (animation-timeline: scroll()){
  @media (prefers-reduced-motion:no-preference){
    .scroll-progress .bar{animation:scrollprog linear both;animation-timeline:scroll(root);animation-range:0% 100%}
    @keyframes scrollprog{from{transform:scaleX(0)}to{transform:scaleX(1)}}
  }
}

/* ---------- top bar ---------- */
.topbar{position:sticky;top:0;z-index:20;backdrop-filter:blur(10px);
  background:color-mix(in srgb, var(--ink) 78%, transparent);
  border-bottom:1px solid var(--line);transition:background .3s ease,border-color .3s ease;}
.topbar .row{max-width:var(--maxw);margin:0 auto;padding:13px 24px;
  display:flex;align-items:center;justify-content:space-between;gap:14px;}
.brand{font-family:var(--mono);font-weight:500;letter-spacing:.04em;font-size:15px;color:var(--text)}
.brand b{color:var(--accent-text);font-weight:500}
.bar-right{display:flex;align-items:center;gap:16px}
.dot{width:8px;height:8px;border-radius:50%;background:var(--ok);animation:pulse 2.6s infinite}
@keyframes pulse{0%{box-shadow:0 0 0 0 rgba(91,185,139,.45)}70%{box-shadow:0 0 0 7px rgba(91,185,139,0)}100%{box-shadow:0 0 0 0 rgba(91,185,139,0)}}
@media (prefers-reduced-motion:reduce){.dot{animation:none}}

.theme-toggle{
  width:34px;height:34px;border-radius:9px;border:1px solid var(--line-2);
  background:transparent;color:var(--text);cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;position:relative;overflow:hidden;
  transition:border-color .18s ease, background .18s ease;
}
.theme-toggle:hover{border-color:var(--accent)}
.theme-toggle svg{
  width:17px;height:17px;position:absolute;top:50%;left:50%;
  transform:translate(-50%,-50%) rotate(0deg) scale(1);opacity:1;
  transition:opacity .45s var(--ease-settled), transform .45s var(--ease-settled);
}
[data-theme="dark"] .theme-toggle .i-moon{opacity:0;transform:translate(-50%,-50%) rotate(-80deg) scale(.4);pointer-events:none}
[data-theme="light"] .theme-toggle .i-sun{opacity:0;transform:translate(-50%,-50%) rotate(80deg) scale(.4);pointer-events:none}
@media (prefers-reduced-motion:no-preference){
  .theme-toggle{transition:border-color .18s ease, transform .18s ease, background .18s ease}
  .theme-toggle:hover{transform:translateY(-1px)}
  .theme-toggle:active{transform:translateY(-1px) scale(.9)}
}
@media (prefers-reduced-motion:reduce){
  .theme-toggle:active{transform:none}
  .theme-toggle svg{transition:opacity .01ms linear;transform:translate(-50%,-50%) !important}
}

/* ---------- mobile menu (hamburger disclosure) ----------
   A dropdown panel anchored to the topbar (position:absolute, so it
   overlays rather than pushing content — no layout-property animation
   involved anywhere here). Reveal is opacity + transform only, and the
   transform is additionally gated so reduced-motion users still get an
   instant, correct end state via the always-on opacity fade. Real
   Tab-trap / outside-click / resize-close logic lives in site.js. */
.menu-toggle{
  display:none;width:34px;height:34px;border-radius:9px;border:1px solid var(--line-2);
  background:transparent;color:var(--text);cursor:pointer;
  align-items:center;justify-content:center;flex:0 0 auto;
  transition:border-color .18s ease, background .18s ease;
}
.menu-toggle:hover{border-color:var(--accent)}
.menu-toggle-bars{position:relative;width:16px;height:11px;display:inline-block}
.menu-toggle-bars span{position:absolute;left:0;right:0;height:1.5px;background:currentColor;border-radius:1px}
.menu-toggle-bars span:nth-child(1){top:0}
.menu-toggle-bars span:nth-child(2){top:50%;transform:translateY(-50%)}
.menu-toggle-bars span:nth-child(3){bottom:0}
.menu-toggle[aria-expanded="true"] .menu-toggle-bars span:nth-child(1){transform:translateY(4.75px) rotate(45deg)}
.menu-toggle[aria-expanded="true"] .menu-toggle-bars span:nth-child(2){opacity:0}
.menu-toggle[aria-expanded="true"] .menu-toggle-bars span:nth-child(3){transform:translateY(-4.75px) rotate(-45deg)}
@media (prefers-reduced-motion:no-preference){
  .menu-toggle-bars span{transition:transform .25s var(--ease-settled), opacity .2s ease}
}

.mobile-menu{
  position:absolute;top:100%;left:0;right:0;
  background:color-mix(in srgb, var(--panel) 97%, transparent);
  border-bottom:1px solid var(--line);backdrop-filter:blur(10px);
  opacity:0;transition:opacity .22s ease;z-index:25;
}
.mobile-menu[hidden]{display:none}
.mobile-menu.open{opacity:1}
@media (prefers-reduced-motion:no-preference){
  .mobile-menu{transform:translateY(-8px);transition:opacity .22s ease, transform .22s var(--ease-settled)}
  .mobile-menu.open{transform:translateY(0)}
}
.mobile-nav{max-width:var(--maxw);margin:0 auto;display:flex;flex-direction:column;padding:4px 24px 16px}
.mobile-nav a{font-family:var(--mono);font-size:14.5px;color:var(--text);padding:14px 2px;border-bottom:1px solid var(--line);display:flex;align-items:center;justify-content:space-between;transition:color .18s ease}
.mobile-nav a:last-child{border-bottom:none}
.mobile-nav a::after{content:"→";color:var(--muted-2);font-size:13px}
.mobile-nav a.gh{color:var(--accent-text)}
.mobile-nav a:hover,.mobile-nav a:focus-visible{color:var(--accent-text)}

@media (max-width:880px){
  .menu-toggle{display:inline-flex}
}

/* back link on subpages */
.backlink{font-family:var(--mono);font-size:13px;color:var(--muted);display:inline-flex;align-items:center;gap:7px;transition:color .18s ease}
.backlink:hover{color:var(--accent-text)}

/* ---------- buttons ---------- */
.btn{font-family:var(--mono);font-size:13.5px;padding:11px 18px;border-radius:9px;
  border:1px solid var(--line-2);color:var(--text);position:relative;overflow:hidden;
  transition:border-color .18s ease, background .18s ease;
  display:inline-flex;align-items:center;gap:9px;cursor:pointer;}
.btn::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(115deg, transparent 35%, color-mix(in srgb, var(--text) 16%, transparent) 50%, transparent 65%);
  transform:translateX(-130%);transition:transform .6s var(--ease-settled);}
.btn.primary::before{background:linear-gradient(115deg, transparent 35%, color-mix(in srgb, var(--btn-ink) 22%, transparent) 50%, transparent 65%)}
.btn:hover{border-color:var(--accent)}
.btn:hover::before{transform:translateX(130%)}
.btn.primary{background:var(--accent);color:var(--btn-ink);border-color:var(--accent);font-weight:500}
.btn.primary:hover{filter:brightness(1.06)}
@media (prefers-reduced-motion:no-preference){
  .btn{transition:border-color .18s ease, background .18s ease, transform .18s ease}
  .btn:hover{transform:translateY(-2px)}
  .btn:active{transform:translateY(-1px) scale(.96)}
}
@media (prefers-reduced-motion:reduce){
  .btn::before{display:none}
  .btn:active{transform:none}
}

/* ---------- section frame ---------- */
section.block{padding:66px 0;border-top:1px solid var(--line)}
.head{margin-bottom:38px}
.head h2{font-family:var(--display);font-weight:600;font-size:clamp(26px,4vw,36px);letter-spacing:-.01em;margin-top:14px}

/* ---------- reveal ---------- */
/* base: quiet paragraphs, meta rows, ctas — a small, settled rise */
.reveal{opacity:0;transform:translateY(16px);
  transition:opacity .7s var(--ease-settled), transform .7s var(--ease-settled)}
.reveal.will-anim{will-change:opacity, transform}
.reveal.in{opacity:1;transform:none}

/* headings rise a touch further, so hierarchy reads in the motion too */
h1.reveal,.head.reveal{
  transform:translateY(26px);
  transition:opacity .8s var(--ease-settled), transform .8s var(--ease-settled)}

/* boxed / card-like elements fade+scale in rather than just sliding */
.card.reveal,.cat.reveal,.job.reveal,.rcol.reveal,.feature.reveal,
.gh-handle.reveal,.shot.reveal,.gh-details.reveal,.contact-inner.reveal{
  transform:translateY(12px) scale(.98);
  transition:opacity .6s var(--ease-settled), transform .6s var(--ease-settled)}

@media (prefers-reduced-motion:reduce){
  .reveal,.reveal.in,h1.reveal,.head.reveal,
  .card.reveal,.cat.reveal,.job.reveal,.rcol.reveal,.feature.reveal,
  .gh-handle.reveal,.shot.reveal,.gh-details.reveal,.contact-inner.reveal{
    opacity:1;transform:none;transition:none}
}

/* ---------- footer ---------- */
footer{border-top:1px solid var(--line);padding:30px 0 46px;margin-top:10px}
footer .row{display:flex;flex-wrap:wrap;gap:10px;justify-content:space-between;font-family:var(--mono);font-size:12.5px;color:var(--muted-2)}


/* ============================================================
   project pages (case studies)
   ============================================================ */
.proj-hero{padding:64px 0 44px}
.proj-hero .eyebrow{margin-bottom:20px}
.proj-lead-row{display:flex;align-items:center;gap:20px;margin-bottom:22px;flex-wrap:wrap}
.proj-hero .logo{width:64px;height:64px;border-radius:15px;border:1px solid var(--line);object-fit:cover;flex:0 0 auto}
.proj-hero h1{font-family:var(--display);font-weight:700;font-size:clamp(36px,7vw,68px);line-height:1;letter-spacing:-.02em}
.proj-hero .lead{font-size:clamp(16px,2.2vw,19px);color:var(--muted);max-width:640px;margin-bottom:26px}
.proj-hero .lead b{color:var(--text);font-weight:600}
.meta{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:26px}
.meta span{font-family:var(--mono);font-size:12px;color:var(--muted);border:1px solid var(--line);border-radius:7px;padding:5px 11px}
.meta span.role{color:var(--accent-text);border-color:var(--accent-text)}

.feature-list{display:grid;grid-template-columns:repeat(2,1fr);gap:14px}
.feature{background:var(--panel);border:1px solid var(--line);border-radius:13px;padding:18px 20px}
.feature h3{font-family:var(--display);font-weight:600;font-size:16.5px;margin-bottom:6px}
.feature p{color:var(--muted);font-size:14px}

/* galleries */
.gallery{margin-top:6px}
.gallery.float{display:grid;grid-template-columns:repeat(2,1fr);gap:34px 26px}
.gallery.float .shot{display:flex;flex-direction:column;align-items:center;gap:14px}
.gallery.float .shot img{max-height:580px;width:auto;max-width:100%;filter:drop-shadow(0 24px 48px rgba(0,0,0,.35))}
[data-theme="light"] .gallery.float .shot img{filter:drop-shadow(0 22px 44px rgba(30,30,40,.18))}

.gallery.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:18px}
.gallery.cards .shot{background:var(--panel);border:1px solid var(--line);border-radius:15px;padding:16px;display:flex;flex-direction:column;align-items:center;gap:14px;transition:border-color .2s ease}
.gallery.cards .shot:hover{border-color:var(--line-2)}
.gallery.cards .shot img{width:100%;max-width:240px;height:auto;border-radius:10px;display:block}
@media (prefers-reduced-motion:no-preference){
  .gallery.cards .shot{transition:border-color .2s ease, transform .2s ease}
  .gallery.cards .shot:hover{transform:translateY(-3px)}
}

.caption{font-family:var(--mono);font-size:12px;color:var(--muted);text-align:center;letter-spacing:.02em}

.next-strip{display:flex;flex-wrap:wrap;gap:12px;justify-content:space-between;align-items:center;margin-top:8px}

@media (max-width:720px){
  .feature-list{grid-template-columns:1fr}
  .gallery.float{grid-template-columns:1fr;gap:30px}
  .gallery.float .shot img{max-height:none;width:min(320px,86%)}
}

/* phone-frame gallery (raw full-screen mobile shots) */
.gallery.frames{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:28px 22px;justify-items:center}
.gallery.frames .shot{display:flex;flex-direction:column;align-items:center;gap:12px;width:100%}
.phone{background:#0b0b0e;border:1px solid var(--line-2);border-radius:30px;padding:7px;box-shadow:0 20px 46px rgba(0,0,0,.4);width:100%;max-width:228px}
[data-theme="light"] .phone{box-shadow:0 18px 40px rgba(30,30,40,.20)}
.phone img{display:block;width:100%;border-radius:24px}

/* wide gallery (admin / web marketing shots) */
.gallery.wide{display:grid;grid-template-columns:1fr 1fr;gap:18px}
.gallery.wide .shot{background:var(--panel);border:1px solid var(--line);border-radius:15px;padding:14px;display:flex;flex-direction:column;align-items:center;gap:12px;transition:border-color .2s ease}
.gallery.wide .shot:hover{border-color:var(--line-2)}
.gallery.wide .shot img{width:100%;height:auto;border-radius:10px;display:block}
@media (prefers-reduced-motion:no-preference){
  .gallery.wide .shot{transition:border-color .2s ease, transform .2s ease}
  .gallery.wide .shot:hover{transform:translateY(-3px)}
}

.subhead{font-family:var(--mono);font-size:12.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--accent-text);margin:0 0 18px}
.subhead + .gallery{margin-bottom:40px}

@media (max-width:720px){
  .gallery.wide{grid-template-columns:1fr}
}

/* ============================================================
   v2: nav, browser frames, card thumbnails, github, motion
   ============================================================ */

/* top nav */
.nav{display:flex;align-items:center;gap:20px}
.nav a{font-family:var(--mono);font-size:13px;color:var(--muted);position:relative;transition:color .18s ease}
.nav a::after{content:"";position:absolute;left:0;right:100%;bottom:-5px;height:1px;background:var(--accent)}
.nav a:hover{color:var(--text)}
.nav a:hover::after{right:0}
@media (prefers-reduced-motion:no-preference){
  .nav a::after{transition:right .25s ease}
}
.nav a.gh{color:var(--accent-text)}
@media (max-width:880px){.nav{display:none}}

/* browser frame for wide web screenshots. Always wrapped in an <a> in this
   codebase, so the hover state goes full accent (same language as
   a.card:hover) rather than the neutral line-2 used by non-interactive
   surfaces — a little extra warmth to match the homepage cards. */
.browser{border:1px solid var(--line);border-radius:13px;overflow:hidden;background:var(--panel);box-shadow:0 18px 42px rgba(0,0,0,.30);transition:border-color .25s ease}
[data-theme="light"] .browser{box-shadow:0 16px 36px rgba(30,30,40,.13)}
.browser:hover{border-color:var(--accent)}
.browser .bar{display:flex;align-items:center;gap:7px;padding:10px 13px;border-bottom:1px solid var(--line);background:var(--panel-2)}
.browser .bar i{width:10px;height:10px;border-radius:50%;background:var(--line-2);display:inline-block}
.browser .bar .url{margin-left:12px;font-family:var(--mono);font-size:11px;color:var(--muted);background:var(--ink);padding:4px 12px;border-radius:6px;border:1px solid var(--line);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.browser img{display:block;width:100%;height:auto}
@media (prefers-reduced-motion:no-preference){
  .browser{transition:transform .25s ease, border-color .25s ease}
  .browser:hover{transform:translateY(-3px)}
}

.gallery.web{display:grid;grid-template-columns:repeat(auto-fit,minmax(360px,1fr));gap:22px}
.gallery.web .shot{display:flex;flex-direction:column;gap:12px}
.gallery.web.single{grid-template-columns:1fr}

/* live-link pill on hero + cards */
.livepill{display:inline-flex;align-items:center;gap:7px;font-family:var(--mono);font-size:11px;color:var(--ok);border:1px solid var(--line-2);border-radius:999px;padding:4px 11px}
.livepill .d{width:7px;height:7px;border-radius:50%;background:var(--ok)}

/* card thumbnails (gallery-linked project cards) */
.thumbwrap{overflow:hidden;border-radius:11px;border:1px solid var(--line);margin-bottom:16px;background:var(--panel-2);aspect-ratio:16/10;position:relative}
.thumbwrap img{display:block;width:100%;height:100%;object-fit:cover;object-position:top}
@media (prefers-reduced-motion:no-preference){
  .thumbwrap img{transition:transform .5s cubic-bezier(.2,.7,.2,1)}
  a.card:hover .thumbwrap img{transform:scale(1.045)}
}
/* bottom scrim on the thumbnail: fades in on hover for a touch of depth.
   Opacity is always-on (the accessible fallback per the motion policy
   above); the slide-up offset is reduced-motion-gated. */
.thumbwrap::after{
  content:"";position:absolute;inset:auto 0 0 0;height:58%;
  background:linear-gradient(to top, color-mix(in srgb, var(--ink) 75%, transparent), transparent);
  opacity:0;transition:opacity .3s ease;pointer-events:none;
}
a.card:hover .thumbwrap::after{opacity:1}
@media (prefers-reduced-motion:no-preference){
  .thumbwrap::after{transform:translateY(14%);transition:opacity .4s ease, transform .45s cubic-bezier(.2,.7,.2,1)}
  a.card:hover .thumbwrap::after{transform:translateY(0)}
}
.card .badge{font-family:var(--mono);font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--accent-text);border:1px solid var(--accent-text);border-radius:6px;padding:2px 8px}
.card .toprow{display:flex;justify-content:space-between;align-items:flex-start;gap:10px;margin-bottom:12px}

/* github section */
.gh-details{border:none}
.gh-summary{list-style:none;cursor:pointer;display:inline-flex;align-items:center;gap:10px;
  font-family:var(--mono);font-size:13.5px;color:var(--text);background:var(--panel);
  border:1px solid var(--line-2);border-radius:9px;padding:11px 18px;user-select:none;
  transition:border-color .18s ease}
.gh-summary::-webkit-details-marker{display:none}
.gh-summary:hover{border-color:var(--accent)}
.gh-summary .chev{width:15px;height:15px;flex:0 0 auto}
@media (prefers-reduced-motion:no-preference){
  .gh-summary .chev{transition:transform .25s ease}
}
.gh-details[open] .gh-summary .chev{transform:rotate(180deg)}
.gh-wrap{display:flex;flex-direction:column;gap:22px;margin-top:22px}

.gh-charts{display:flex;flex-direction:column;gap:16px}
.gh-chart{background:var(--panel);border:1px solid var(--line);border-radius:15px;padding:22px}
.gh-chart .lbl{font-family:var(--mono);font-size:12px;color:var(--muted);margin-bottom:14px;display:flex;align-items:center;gap:8px}
.gh-chart .lbl .tag-primary{margin-left:auto;color:var(--accent-text);font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;border:1px solid var(--accent-text);border-radius:6px;padding:2px 8px}
.gh-chart img{width:100%;height:auto;display:block}
.gh-chart .fallback{color:var(--muted);font-size:14px}

.gh-handles{display:flex;flex-direction:column;gap:10px}
.gh-handle{display:flex;align-items:center;justify-content:space-between;gap:12px;background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:14px 18px;transition:border-color .2s ease}
.gh-handle:hover{border-color:var(--accent)}
@media (prefers-reduced-motion:no-preference){
  .gh-handle:hover{transform:translateX(3px);transition:transform .2s ease, border-color .2s ease}
}
.gh-handle .h{display:flex;align-items:center;gap:11px}
.gh-handle .h svg{width:19px;height:19px;flex:0 0 auto}
.gh-handle .name{font-family:var(--mono);font-size:14px;color:var(--text)}
.gh-handle .tag{font-family:var(--mono);font-size:11px;color:var(--muted-2)}
.gh-handle .go{font-family:var(--mono);font-size:12px;color:var(--accent-text)}

@media (max-width:720px){
  .gallery.web{grid-template-columns:1fr}
  .browser .bar .url{font-size:10px}
}

/* confidential thumbnail (archived / private projects) */
.thumbwrap.confidential{display:flex;align-items:center;justify-content:center;border-style:dashed;
  background:repeating-linear-gradient(45deg, transparent, transparent 11px, color-mix(in srgb, var(--muted-2) 9%, transparent) 11px, color-mix(in srgb, var(--muted-2) 9%, transparent) 22px), var(--panel-2)}
.thumbwrap.confidential .conf{display:flex;flex-direction:column;align-items:center;gap:9px}
.thumbwrap.confidential .conf svg{width:24px;height:24px;color:var(--accent-text)}
.thumbwrap.confidential .conf span{font-family:var(--mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted)}
