/* ============================================================
   base.css — tokens, reset, typography, buttons, shared bits
   ============================================================ */
:root{
  --bg:        #0B0C10;
  --bg2:       #101218;
  --surface:   #14161E;
  --line:      rgba(var(--ink-rgb),.10);
  --ink:       #F5F3EE;
  --muted:     #9AA0AC;
  --sapphire:  #3D7BFF;
  --sapphire-deep: #0F52BA;
  --canary:    #FFD23D;
  --danger:    #FF5D5D;
  --radius:    18px;
  --ease:      cubic-bezier(.22,.61,.36,1);
  --t:         300ms var(--ease);
  --font-disp: "Archivo", system-ui, sans-serif;
  --font-body: "Space Grotesk", system-ui, sans-serif;
  --nav-h:     72px;
  /* theme-flippable channel + semantic tokens */
  --sapphire-rgb: 61,123,255;
  --canary-rgb:   255,210,61;
  /* orb glow tokens — per-theme. Dark renders orbs as ADDITIVE light:
     --orb-blend:screen (normal alpha-compositing over the near-black bg always
     muddies the hue — nothing survives it) and --orb-round:0 (a
     border-radius:50% clip terminates the glow at a hard radius, which reads as a
     disc edge on dark; unclipped, the fill feathers to alpha 0 at 100% =
     farthest-corner, so nothing ever terminates). Light keeps normal/50%, where
     its fills may run past the ~71% clip point because leftover alpha is invisible
     on cream. INVARIANT (dark): fills must be sized `circle closest-side` and end
     alpha 0 at 100% — closest-side makes 100% the box edge, so the glow dies
     exactly where the box does; default (farthest-corner) sizing leaves live alpha
     at the straight box edges, which screen-blend renders as hard seam lines.
     Screen also amplifies brightness, so alphas run lower than they look.
     Blur must stay ~0 on the masked orbs (b/b2/c): the cursor-pocket mask clips
     painting to the border box, so any blur halo gets truncated into a seam;
     the multi-stop closest-side gradient provides the softness instead — and
     with no blur to hide them, stops must be DENSE (~every 10%) on a smooth
     decay curve: sparse stops make each linear-interp slope break read as a
     concentric ring edge (Mach banding). The curve must be gaussian-shaped
     (flat slope at 0%) — a quadratic peak makes a bright point at the center —
     and single-hue: even a faint --glow-warm-rgb center stop reads as a
     separate inner disc where the hue hands off. The tail must also LAND
     gently: near 100%, adjacent stops may differ by ≤~.005 alpha (≈1 channel
     level over this bg) — cutting a fatter tail straight to 0 at the circle
     edge reads as a faint circular rim. */
  --orb-blend: screen;
  --orb-round: 0;
  --orb-core-rgb: 61,123,255;
  --orb-faint-a: .26;
  --orb-warm-a: .38;
  --orb-soft-blur: 0px;
  --glow-warm-rgb: 140,180,255;
  --orb-fill-hero: radial-gradient(circle closest-side at 50% 50%,
    rgba(var(--orb-core-rgb),.22) 0%,
    rgba(var(--orb-core-rgb),.213) 10%,
    rgba(var(--orb-core-rgb),.193) 20%,
    rgba(var(--orb-core-rgb),.163) 30%,
    rgba(var(--orb-core-rgb),.130) 40%,
    rgba(var(--orb-core-rgb),.096) 50%,
    rgba(var(--orb-core-rgb),.067) 60%,
    rgba(var(--orb-core-rgb),.044) 70%,
    rgba(var(--orb-core-rgb),.024) 80%,
    rgba(var(--orb-core-rgb),.013) 86%,
    rgba(var(--orb-core-rgb),.006) 92%,
    rgba(var(--orb-core-rgb),.002) 96%,
    rgba(var(--orb-core-rgb),0) 100%);
  --orb-fill-mid: radial-gradient(circle closest-side at 50% 50%,
    rgba(var(--orb-core-rgb),.16) 0%,
    rgba(var(--orb-core-rgb),.155) 10%,
    rgba(var(--orb-core-rgb),.140) 20%,
    rgba(var(--orb-core-rgb),.119) 30%,
    rgba(var(--orb-core-rgb),.094) 40%,
    rgba(var(--orb-core-rgb),.070) 50%,
    rgba(var(--orb-core-rgb),.049) 60%,
    rgba(var(--orb-core-rgb),.032) 70%,
    rgba(var(--orb-core-rgb),.017) 80%,
    rgba(var(--orb-core-rgb),.009) 86%,
    rgba(var(--orb-core-rgb),.004) 92%,
    rgba(var(--orb-core-rgb),.002) 96%,
    rgba(var(--orb-core-rgb),0) 100%);
  --ink-rgb:      245,243,238;
  --veil-rgb:     16,18,24;
  --sapphire-hover: #5b90ff;
  /* hero accent word swaps roles per theme: canary on dark, sapphire on light */
  --hero-accent:     var(--canary);
  --hero-accent-rgb: var(--canary-rgb);
  /* before/after compare elevation — per theme: the heavy black shadow reads as
     depth on dark but as a grey haze band on cream (the carousel viewport also
     clips it at the image edges), so light gets a tight, faint one */
  --ba-shadow:    0 24px 80px rgba(0,0,0,.5);
  --on-accent:    #fff;
  --success:      #4ADE80;
  color-scheme: dark;
}

html[data-theme="light"]{
  --bg:#FAF7F2; --bg2:#F1EDE4; --surface:#FFFDF9;
  --ink:#14161E; --muted:#5A6170;
  --line:rgba(20,22,30,.13);
  --sapphire:#2B5FD9;          /* darker for AA text/links on light */
  --sapphire-deep:#0F52BA;
  --sapphire-hover:#1E4FC4;
  --canary:#8A6A00;            /* canary-as-text needs dark amber on light */
  --sapphire-rgb:43,95,217;
  --canary-rgb:255,190,10;
  /* orb fills keep v1's pale glow on cream, not the AA-darkened canary */
  --orb-blend:normal;
  --orb-round:50%;
  --orb-core-rgb:255,210,61;
  --orb-faint-a:.22;
  --orb-warm-a:.35;
  --orb-soft-blur:26px;
  --glow-warm-rgb:255,240,190;
  --orb-fill-hero:radial-gradient(circle at 50% 50%,
    rgba(var(--orb-core-rgb),.5) 0%,
    rgba(var(--glow-warm-rgb),.34) 48%,
    rgba(var(--glow-warm-rgb),0) 85%);
  --orb-fill-mid:radial-gradient(circle at 50% 50%,
    rgba(var(--orb-core-rgb),.45) 0%,
    rgba(var(--glow-warm-rgb),.28) 42%,
    rgba(var(--glow-warm-rgb),0) 72%);
  --ink-rgb:20,22,30;
  --veil-rgb:250,247,242;
  --hero-accent:var(--sapphire);
  --hero-accent-rgb:var(--sapphire-rgb);
  --ba-shadow:0 10px 28px rgba(20,22,30,.10);
  --on-accent:#fff;
  --success:#15803D;
  color-scheme: light;
}
/* .ba-lbl pill stays dark on photos — pin readable text colors under light tokens */
html[data-theme="light"] .ba-lbl{ color:#9AA0AC; }
html[data-theme="light"] .ba-lbl.after{ color:#FFD23D; }

*{ margin:0; padding:0; box-sizing:border-box; }
html{ scroll-behavior:smooth; }
html.reduced-motion{ scroll-behavior:auto; }
body{
  background:var(--bg);
  color:var(--ink);
  font-family:var(--font-body);
  font-size:17px;
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
  overflow-x:clip;
}
body::before{ /* one continuous canvas: faint vertical drift from bg to bg2 and back */
  content:""; position:fixed; inset:0; z-index:-2;
  background:
    radial-gradient(1200px 800px at 85% -10%, rgba(var(--sapphire-rgb),.10), transparent 60%),
    radial-gradient(1000px 700px at 10% 110%, rgba(var(--canary-rgb),.06), transparent 60%),
    linear-gradient(180deg, var(--bg), var(--bg2) 55%, var(--bg));
}

img{ max-width:100%; display:block; }
a{ color:var(--ink); text-decoration:none; }
button{ font:inherit; color:inherit; background:none; border:0; cursor:pointer; }
::selection{ background:var(--sapphire); color:var(--on-accent); }

h1,h2,h3,h4{ font-family:var(--font-disp); font-weight:700; line-height:1.08; letter-spacing:-.02em; }

.container{ width:min(1160px, 92vw); margin:0 auto; }

/* section rhythm */
section, .hero{ position:relative; }
.section-head{ margin-bottom:clamp(36px,6vw,72px); }
.eyebrow{
  display:inline-flex; align-items:center; gap:10px;
  font-size:13px; font-weight:600; letter-spacing:.22em; text-transform:uppercase;
  color:var(--sapphire);
}
.eyebrow::before{ content:""; width:26px; height:2px; background:var(--sapphire); }
.sec-title{ font-size:clamp(34px, 5.4vw, 68px); margin-top:14px; }
.sec-title-sm{ font-size:clamp(26px, 3.4vw, 40px); margin-bottom:18px; }
.sec-sub{ color:var(--muted); margin-top:16px; max-width:640px; font-size:1.08rem; }

/* buttons */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:10px;
  padding:15px 30px; border-radius:999px;
  font-family:var(--font-body); font-weight:600; font-size:16px;
  transition:transform var(--t), box-shadow var(--t), background var(--t), color var(--t), border-color var(--t);
  border:1.5px solid transparent;
  min-height:48px;
}
.btn-primary{
  background:var(--sapphire); color:var(--on-accent);
  box-shadow:0 0 0 rgba(var(--sapphire-rgb),0), 0 8px 30px rgba(var(--sapphire-rgb),.35);
}
.btn-primary:hover{ background:var(--sapphire-hover); box-shadow:0 0 26px rgba(var(--sapphire-rgb),.55), 0 8px 34px rgba(var(--sapphire-rgb),.4); }
.btn-ghost{
  border-color:var(--line); color:var(--ink); background:rgba(var(--ink-rgb),.03);
}
.btn-ghost:hover{ border-color:var(--sapphire); color:var(--ink); background:rgba(var(--sapphire-rgb),.10); }
.btn-danger{ background:rgba(255,93,93,.12); color:var(--danger); border-color:rgba(255,93,93,.4); }
.btn-danger:hover{ background:rgba(255,93,93,.22); }

/* focus */
:focus-visible{ outline:2px solid var(--canary); outline-offset:3px; border-radius:4px; }

/* orbs (decorative glows) */
.orb{ position:absolute; border-radius:var(--orb-round, 50%); mix-blend-mode:var(--orb-blend, normal); filter:blur(70px); pointer-events:none; z-index:-1; }

/* toast */
.toast{
  position:fixed; left:50%; bottom:28px; transform:translate(-50%, 20px);
  background:var(--surface); color:var(--ink);
  border:1px solid var(--line); border-radius:14px;
  padding:14px 22px; font-size:15px; max-width:min(480px, 90vw);
  opacity:0; pointer-events:none; z-index:120;
  transition:opacity var(--t), transform var(--t);
  box-shadow:0 12px 40px rgba(0,0,0,.5);
}
.toast.show{ opacity:1; transform:translate(-50%, 0); }

/* modals — must sit ABOVE the fixed admin bar (z-index 110): the editor sheets'
   Save/Cancel row reaches the bottom of shorter viewports, and a lower modal
   z-index lets the admin bar intercept those clicks */
.modal{ position:fixed; inset:0; z-index:115; display:none; }
.modal.open{ display:block; }
.scrim{ position:absolute; inset:0; background:rgba(5,6,9,.72); backdrop-filter:blur(6px); }
.sheet{
  position:relative; margin:6vh auto 0; width:min(560px, 92vw);
  max-height:86vh; overflow-y:auto;
  background:var(--surface); border:1px solid var(--line); border-radius:var(--radius);
  padding:34px; box-shadow:0 30px 80px rgba(0,0,0,.6);
}
.sheet-wide{ width:min(760px, 94vw); }
.sheet h3{ font-size:26px; margin-bottom:16px; }
.sheet h4{ font-size:15px; margin:26px 0 10px; color:var(--sapphire); letter-spacing:.06em; text-transform:uppercase; }
.sheet-body p{ margin-bottom:12px; color:var(--muted); }
.sheet-x{
  position:absolute; top:16px; right:16px; width:38px; height:38px;
  border-radius:50%; border:1px solid var(--line); color:var(--muted);
  transition:color var(--t), border-color var(--t);
}
.sheet-x:hover{ color:var(--ink); border-color:var(--ink); }
body.modal-open{ overflow:hidden; }

/* form fields (shared by contact + editors) */
input[type="text"], input[type="email"], input[type="url"], input[type="number"], textarea{
  width:100%; padding:13px 16px;
  background:rgba(var(--ink-rgb),.04); color:var(--ink);
  border:1.5px solid var(--line); border-radius:12px;
  font:inherit; font-size:16px;
  transition:border-color var(--t), background var(--t);
}
input:focus, textarea:focus{ outline:none; border-color:var(--sapphire); background:rgba(var(--sapphire-rgb),.06); }
textarea{ resize:vertical; min-height:90px; }
label > span{ display:block; font-size:13px; font-weight:600; color:var(--muted); margin-bottom:6px; letter-spacing:.04em; }

select{
  width:100%; padding:13px 16px;
  background:rgba(var(--ink-rgb),.04); color:var(--ink);
  border:1.5px solid var(--line); border-radius:12px;
  font:inherit; font-size:16px;
  transition:border-color var(--t), background var(--t);
}
select:focus{ outline:none; border-color:var(--sapphire); background:rgba(var(--sapphire-rgb),.06); }

/* editor grids */
.ed-grid{ display:grid; grid-template-columns:1fr 1fr; gap:16px; }
.ed-grid .ed-full{ grid-column:1 / -1; }
.ed-img{ display:flex; flex-direction:column; gap:8px; }
.ed-img > span{ font-size:13px; font-weight:600; color:var(--muted); }
.ed-preview{
  height:120px; border:1.5px dashed var(--line); border-radius:12px;
  display:flex; align-items:center; justify-content:center;
  color:var(--muted); font-size:13px; overflow:hidden;
}
.ed-preview img{ width:100%; height:100%; object-fit:cover; border-radius:10px; }
.ed-actions{ display:flex; gap:12px; margin-top:26px; align-items:center; }
.ed-actions .spacer{ flex:1; }

/* gallery editor thumbs */
.gal-edit{ display:flex; flex-wrap:wrap; gap:10px; min-height:10px; }
.gal-thumb{
  position:relative; width:92px; height:62px; border-radius:10px; overflow:hidden;
  border:1px solid var(--line); display:block;
}
.gal-thumb img{ width:100%; height:100%; object-fit:cover; }
.gal-x{
  position:absolute; top:4px; right:4px; width:22px; height:22px;
  border-radius:50%; background:rgba(5,6,9,.75); color:#fff;
  font-size:11px; line-height:1; display:flex; align-items:center; justify-content:center;
}
.gal-x:hover{ background:var(--danger); }

/* collapsible case-study fields in the project editor */
.cs-fields{ border:1px solid var(--line); border-radius:12px; padding:0 16px; }
.cs-fields summary{
  cursor:pointer; padding:14px 0; font-size:13px; font-weight:600;
  color:var(--muted); letter-spacing:.04em;
}
.cs-fields[open]{ padding-bottom:16px; }

/* round avatar preview in the review editor */
.ed-preview-av{ width:72px; height:72px; border-radius:50%; flex:0 0 auto; }
.ed-preview-av img{ border-radius:50%; }
@media (max-width:640px){ .ed-grid{ grid-template-columns:1fr; } }

/* admin-only elements hidden for visitors */
.admin-only{ display:none !important; }
body.admin .admin-only{ display:block !important; }
body.admin .admin-row.admin-only{ display:flex !important; gap:10px; margin-top:14px; }

/* honeypot */
.hp{ position:absolute !important; left:-9999px !important; opacity:0; }
