  :root{
    --paper:#F4F3EF; --paper-2:#FBFAF8; --card:#FCFBF9;
    --ink:#1B1916; --ink-2:#6E6A60; --ink-3:#9A968C;
    --line:#E4E1D9; --line-2:#D8D4CA;
    --glow:#FF9E2C; --glow-2:#FFC061; --glow-ring:rgba(255,158,44,.28);
    --shade:#DAD6CC; --shade-hi:#EFEBE1; --shade-lo:#C3BEB2;
    --btn-ink:#1B1916; --btn-text:#F6F4EF;
    --shadow:0 1px 2px rgba(30,26,20,.05), 0 12px 34px -18px rgba(30,26,20,.22);
    --maxw:1180px;
    --z-header:40; --z-scrim:60; --z-detail:70; --z-drawer:80; --z-skip:90;
    --serif:"Iowan Old Style","Palatino Linotype",Palatino,Georgia,serif;
    --sans:"Helvetica Neue",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Arial,sans-serif;
    --mono:ui-monospace,"SF Mono","Menlo","Cascadia Mono",Consolas,monospace;
  }
  @media (prefers-color-scheme:dark){
    :root{
      --paper:#100F0C; --paper-2:#16140F; --card:#1A1813;
      --ink:#F1EFE7; --ink-2:#A29D91; --ink-3:#75705F;
      --line:#2A2721; --line-2:#332F27;
      --glow:#FFB24C; --glow-2:#FFD08A; --glow-ring:rgba(255,178,76,.30);
      --shade:#2C2822; --shade-hi:#3C372E; --shade-lo:#211E19;
      --btn-ink:#F1EFE7; --btn-text:#14130F;
      --shadow:0 1px 2px rgba(0,0,0,.4), 0 18px 44px -20px rgba(0,0,0,.7);
    }
  }
  :root[data-theme="light"]{
    --paper:#F4F3EF; --paper-2:#FBFAF8; --card:#FCFBF9;
    --ink:#1B1916; --ink-2:#6E6A60; --ink-3:#9A968C;
    --line:#E4E1D9; --line-2:#D8D4CA;
    --glow:#FF9E2C; --glow-2:#FFC061; --glow-ring:rgba(255,158,44,.28);
    --shade:#DAD6CC; --shade-hi:#EFEBE1; --shade-lo:#C3BEB2;
    --btn-ink:#1B1916; --btn-text:#F6F4EF;
    --shadow:0 1px 2px rgba(30,26,20,.05), 0 12px 34px -18px rgba(30,26,20,.22);
  }
  :root[data-theme="dark"]{
    --paper:#100F0C; --paper-2:#16140F; --card:#1A1813;
    --ink:#F1EFE7; --ink-2:#A29D91; --ink-3:#75705F;
    --line:#2A2721; --line-2:#332F27;
    --glow:#FFB24C; --glow-2:#FFD08A; --glow-ring:rgba(255,178,76,.30);
    --shade:#2C2822; --shade-hi:#3C372E; --shade-lo:#211E19;
    --btn-ink:#F1EFE7; --btn-text:#14130F;
    --shadow:0 1px 2px rgba(0,0,0,.4), 0 18px 44px -20px rgba(0,0,0,.7);
  }

  *{box-sizing:border-box}
  body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--sans);line-height:1.6;
    -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;transition:background .5s ease,color .5s ease}
  .wrap{max-width:var(--maxw);margin:0 auto;padding:0 24px}
  a{color:inherit;text-decoration:none}
  img{max-width:100%;display:block}
  h1,h2,h3{margin:0;font-weight:400;letter-spacing:-.02em;text-wrap:balance;line-height:1.05}
  .eyebrow{font-family:var(--mono);font-size:11px;letter-spacing:.22em;text-transform:uppercase;color:var(--ink-2)}
  .mono{font-family:var(--mono);font-variant-numeric:tabular-nums}
  :focus-visible{outline:2px solid var(--glow);outline-offset:3px;border-radius:2px}

  /* Off-screen until focused (Tab from page load), not display:none — a
     hidden element can't receive focus at all, so it has to stay in the
     layout and just be moved out of the viewport. z-index uses the same
     --z-* scale as the header/scrim/detail/drawer rather than a bare
     number, and sits above all of them (90 > --z-drawer's 80): the skip
     link only ever has focus at the very start of a Tab walk, before any
     overlay could be open, but it should still win unambiguously. */
  .skip{position:absolute;left:-9999px;top:8px;z-index:var(--z-skip);background:var(--card);
    border:1px solid var(--line-2);border-radius:8px;padding:10px 16px}
  .skip:focus{left:16px}

  .ticker{background:var(--ink);color:var(--paper);font-family:var(--mono);font-size:11px;letter-spacing:.14em;
    text-transform:uppercase;text-align:center;padding:8px 16px}
  header{position:sticky;top:0;z-index:var(--z-header);background:color-mix(in srgb,var(--paper) 82%,transparent);
    backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);border-bottom:1px solid var(--line)}
  .nav{display:flex;align-items:center;justify-content:space-between;height:64px;gap:20px}
  .brand{font-size:22px;letter-spacing:-.01em;display:flex;align-items:center;gap:1px}
  .brand b{font-weight:600}.brand .deg{color:var(--glow);font-weight:600}
  .navlinks{display:flex;gap:26px;font-size:14px;color:var(--ink-2)}
  .navlinks a{transition:color .2s}.navlinks a:hover{color:var(--ink)}
  .navtools{display:flex;align-items:center;gap:6px}
  .iconbtn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:38px;padding:0 12px;
    border:1px solid var(--line-2);border-radius:999px;background:transparent;color:var(--ink);
    font-family:var(--mono);font-size:12px;cursor:pointer;transition:border-color .2s,background .2s}
  .iconbtn:hover{border-color:var(--ink-3)}
  .menuBtn{display:none}
  .mobileMenu{overflow:hidden;max-height:0;transition:max-height .35s ease;border-bottom:1px solid transparent}
  .mobileMenu.open{max-height:360px;border-bottom-color:var(--line)}
  .mobileMenu .inner{padding:10px 24px 20px;display:flex;flex-direction:column;gap:2px}
  .mobileMenu a{padding:12px 4px;border-bottom:1px solid var(--line);font-size:16px}
  @media(max-width:680px){.navlinks{display:none}.menuBtn{display:inline-flex}}
  @media(min-width:681px){.mobileMenu{display:none}}

  /* ---------- lamp rendering ---------- */
  .lamp{position:relative;width:100%;aspect-ratio:1/1;display:grid;place-items:center;isolation:isolate}
  .lamp .stagefloor{position:absolute;bottom:8%;left:50%;transform:translateX(-50%);width:66%;height:5%;
    border-radius:50%;background:radial-gradient(closest-side,rgba(0,0,0,.16),transparent);filter:blur(3px)}
  .lamp .glow{position:absolute;inset:-6% -6% 8% -6%;border-radius:50%;
    background:radial-gradient(circle at 50% 42%,var(--glow-2),var(--glow) 26%,transparent 62%);
    filter:blur(16px);opacity:.05;transform:scale(.9);transition:opacity .7s ease,transform .7s ease;z-index:-1}
  /* Generated lamp art is 2:3 portrait. object-fit:contain fits to the shorter
     axis, so a small photo box in a square stage leaves the lamp tiny with dead
     space either side. Give the photo almost the whole stage and let the stage's
     own aspect-ratio (see .card .lamp) control how much room it has. */
  /* inset must be 0. A 1% inset left a ~3px strip inside the lamp box that the
     photo did not cover, and the blurred .glow (z-index:-1 inside isolation:isolate)
     showed through it as a hard vertical seam beside the lamp — visible on any
     colorway dark enough to contrast with the halo. object-fit:contain means a
     full-box photo still never distorts. */
  .lamp .photo{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;
    transition:opacity .45s ease,filter .6s ease}
  .lamp .photo-off{opacity:1}
  .lamp .photo-on{opacity:0}
  .lamp.on .photo-off{opacity:0}
  .lamp.on .photo-on{opacity:1}
  .card:hover .lamp .photo-off,.card:focus-within .lamp .photo-off{opacity:0}
  .card:hover .lamp .photo-on,.card:focus-within .lamp .photo-on{opacity:1}
  .lamp .photo-warm{position:absolute;inset:0;pointer-events:none;opacity:0;transition:opacity .6s ease;
    background:radial-gradient(60% 45% at 50% 42%,var(--glow-2),transparent 62%);mix-blend-mode:soft-light;z-index:2}
  .lamp .base{position:absolute;bottom:6%;left:50%;transform:translateX(-50%);width:34%;height:3.5%;border-radius:50%;
    background:linear-gradient(var(--shade-lo),var(--shade));box-shadow:0 6px 14px -6px rgba(0,0,0,.35)}
  .lamp .form{position:relative;width:52%;height:74%;margin-bottom:9%;
    background:linear-gradient(90deg,var(--shade-lo),var(--shade-hi) 34%,var(--shade-hi) 60%,var(--shade-lo)),var(--shade);
    box-shadow:inset 0 0 0 1px rgba(0,0,0,.04);overflow:hidden;transition:filter .6s ease}
  .lamp .form::before{content:"";position:absolute;inset:0;
    background:repeating-linear-gradient(90deg,rgba(0,0,0,.09) 0 1px,transparent 1px 8px);mix-blend-mode:multiply;opacity:.5}
  .lamp .form::after{content:"";position:absolute;inset:0;opacity:0;transition:opacity .6s ease;
    background:radial-gradient(120% 80% at 50% 32%,var(--glow-2),transparent 60%),
      linear-gradient(180deg,var(--glow-2),var(--glow) 55%,color-mix(in srgb,var(--glow) 70%,#7a3d00))}
  .lamp[data-shape="cylinder"] .form{border-radius:40px 40px 10px 10px}
  .lamp[data-shape="taper"] .form{clip-path:polygon(28% 0,72% 0,100% 100%,0 100%);border-radius:0}
  .lamp[data-shape="orb"] .form{width:62%;height:62%;border-radius:50%;margin-bottom:13%}
  .lamp[data-shape="orb"] .form::before{background:repeating-linear-gradient(0deg,rgba(0,0,0,.08) 0 1px,transparent 1px 9px)}
  .lamp[data-shape="dome"] .form{border-radius:120px 120px 12px 12px;height:70%}
  .lamp[data-shape="stack"] .form{border-radius:8px;
    background:repeating-linear-gradient(180deg,var(--shade-hi) 0 12%,var(--shade-lo) 12% 12.5%),var(--shade)}
  .lamp[data-shape="wave"] .form{border-radius:70px 70px 12px 12px}
  .lamp[data-shape="wave"] .form::before{
    background:repeating-linear-gradient(90deg,rgba(0,0,0,.10) 0 1px,transparent 1px 6px),
      repeating-linear-gradient(0deg,transparent 0 22px,rgba(0,0,0,.05) 22px 24px)}
  .lamp.on .glow{opacity:1;transform:scale(1.05)}
  .lamp.on .form::after{opacity:.9}.lamp.on .form{filter:saturate(1.05)}
  .lamp.on .photo{filter:brightness(1.1) saturate(1.08)}.lamp.on .photo-warm{opacity:.85}
  .card:hover .lamp .glow{opacity:1;transform:scale(1.05)}
  .card:hover .lamp .form::after{opacity:.88}
  .card:hover .lamp .photo{filter:brightness(1.1) saturate(1.08)}
  .card:hover .lamp .photo-warm{opacity:.8}

  /* custom (color-swappable) lamp */
  .lamp.custom .form{background-color:var(--body,#ECE7DC);
    background-image:linear-gradient(90deg,rgba(0,0,0,.16),transparent 26%,transparent 74%,rgba(0,0,0,.16));
    transition:background-color .45s ease,filter .6s ease}
  .lamp.custom .base{background-color:var(--basecol,#2A2A2E);background-image:none;transition:background-color .45s ease}
  .lamp.custom.on .form::after{opacity:.7;mix-blend-mode:screen}

  /* image slots */
  .imgslot{position:relative;overflow:hidden;border-radius:14px;border:1px solid var(--line);
    background:linear-gradient(140deg,var(--paper-2),var(--card));display:grid;place-items:center}
  .imgslot img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
  .imgslot .ph{text-align:center;color:var(--ink-3);font-family:var(--mono);padding:16px}
  .imgslot .ph .ic{font-size:22px;opacity:.7;margin-bottom:8px}
  .imgslot .ph .t{font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-2)}
  .imgslot .ph .s{font-size:10px;letter-spacing:.1em;color:var(--ink-3);margin-top:4px}

  /* hero */
  .hero{padding:64px 0 44px;border-bottom:1px solid var(--line)}
  .hero-grid{display:grid;grid-template-columns:1.05fr .95fr;gap:40px;align-items:center}
  .hero h1{font-size:clamp(44px,7.2vw,88px);font-weight:300;letter-spacing:-.035em}
  .hero h1 em{font-family:var(--serif);font-style:italic;font-weight:400}
  .hero p.lede{font-size:18px;color:var(--ink-2);max-width:44ch;margin:22px 0 30px}
  .cta-row{display:flex;flex-wrap:wrap;gap:12px;align-items:center}
  .btn{display:inline-flex;align-items:center;gap:10px;height:50px;padding:0 26px;border-radius:999px;
    background:var(--btn-ink);color:var(--btn-text);border:1px solid var(--btn-ink);font-size:15px;cursor:pointer;
    transition:transform .15s ease,opacity .2s}
  .btn:hover{transform:translateY(-1px)}
  .btn.ghost{background:transparent;color:var(--ink);border-color:var(--line-2)}
  .btn.ghost:hover{border-color:var(--ink-3)}
  .hero-stage{position:relative;min-height:360px;display:grid;place-items:center;
    background:radial-gradient(80% 70% at 50% 40%,var(--paper-2),transparent 75%);border-radius:20px}
  /* 5:7 to match the 2:3 art, like the cards and the modal — a 1:1 hero stage
     letterboxed the lamp to roughly half the width it could use. */
  .hero-stage .lamp{max-width:440px;aspect-ratio:5/7}
  .hero-meta{display:flex;gap:26px;margin-top:26px;flex-wrap:wrap}
  .hero-meta div{display:flex;flex-direction:column}
  .hero-meta .k{font-family:var(--mono);font-size:22px;font-variant-numeric:tabular-nums}
  .hero-meta .l{font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)}
  @media(max-width:820px){.hero-grid{grid-template-columns:1fr;gap:8px}.hero-stage{order:-1;min-height:320px}}

  section{padding:72px 0}
  .sec-head{display:flex;justify-content:space-between;align-items:flex-end;gap:20px;margin-bottom:34px;flex-wrap:wrap}
  .sec-head h2{font-size:clamp(28px,4vw,40px);font-weight:300}

  .grid{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
  @media(max-width:900px){.grid{grid-template-columns:repeat(2,1fr)}}
  @media(max-width:560px){.grid{grid-template-columns:1fr}}
  .card{position:relative;background:var(--card);border:1px solid var(--line);border-radius:16px;padding:16px;display:flex;
    flex-direction:column;box-shadow:var(--shadow);cursor:pointer;transition:transform .3s ease,border-color .3s ease}
  .card:hover{transform:translateY(-4px);border-color:var(--line-2)}
  .card-open{position:absolute;inset:0;z-index:1;display:block;background:none;border:none;
    cursor:pointer;font:inherit;color:transparent;padding:0;text-decoration:none}
  .card .add{position:relative;z-index:2}
  .card .stage{position:relative;background:radial-gradient(70% 60% at 50% 45%,var(--paper-2),transparent 78%);
    border-radius:10px;padding:8px}
  /* The art is 2:3 portrait. Two things were shrinking it: a max-width cap that left
     the stage's full width unused, and a container ratio wider than the art, which
     makes object-fit:contain fit to height and waste the sides. So: no width cap, and
     a 5:7 container — close enough to 2:3 that almost nothing is letterboxed, without
     making the card absurdly tall. Only the card stage changes; the hero, detail modal
     and configurator keep 1:1, which the CSS-lamp fallback geometry depends on. */
  .card .lamp{width:100%;aspect-ratio:5/7;margin:0 auto}
  .card .stage{padding:4px}
  /* .lamp .glow deliberately bleeds past the lamp box (inset:-6%) so the halo isn't
     cut off. Where a lamp is viewport-wide that bleed becomes horizontal page scroll.
     Clip on the CARD (rounded, so the edge is invisible) and on the full-bleed HERO
     SECTION (whose edges are off-screen) — never on the stage itself, which turns a
     soft halo into a hard-edged rectangle. Not overflow-x:hidden on <body>, which
     would also mask genuine layout overflow. */
  .card{overflow:hidden}
  .hero{overflow:hidden}
  .badge{position:absolute;top:10px;left:10px;font-family:var(--mono);font-size:10px;letter-spacing:.12em;
    text-transform:uppercase;color:var(--glow);border:1px solid var(--glow-ring);padding:3px 8px;border-radius:999px;background:var(--card)}
  .viewhint{position:absolute;bottom:12px;right:12px;font-family:var(--mono);font-size:10px;letter-spacing:.1em;
    text-transform:uppercase;color:var(--ink-3);opacity:0;transition:opacity .25s}
  .card:hover .viewhint{opacity:1}
  .card .info{padding:14px 4px 4px;display:flex;flex-direction:column;gap:4px}
  .card .row1{display:flex;justify-content:space-between;align-items:baseline;gap:10px}
  .card .name{font-size:19px}
  .card .price{font-family:var(--mono);font-size:16px;font-variant-numeric:tabular-nums}
  .card .blurb{color:var(--ink-2);font-size:13.5px;min-height:38px}
  .cust-chip{display:inline-flex;align-items:center;gap:6px;align-self:flex-start;margin:2px 0 2px;
    font-family:var(--mono);font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--glow);
    border:1px solid var(--glow-ring);border-radius:999px;padding:3px 9px}
  .specs{display:flex;gap:14px;flex-wrap:wrap;margin:8px 0 14px;font-family:var(--mono);font-size:11px;color:var(--ink-3);letter-spacing:.04em}
  .specs b{color:var(--ink-2);font-weight:400}
  .add{margin-top:auto;height:44px;border-radius:10px;border:1px solid var(--line-2);background:transparent;color:var(--ink);
    font-family:var(--mono);font-size:12.5px;letter-spacing:.08em;text-transform:uppercase;cursor:pointer;
    transition:background .2s,color .2s,border-color .2s}
  .add:hover{background:var(--btn-ink);color:var(--btn-text);border-color:var(--btn-ink)}

  /* ---------- customize feature band ---------- */
  .customize-band{position:relative;overflow:hidden;border-top:1px solid var(--line);border-bottom:1px solid var(--line);
    background:radial-gradient(55% 120% at 82% 50%,var(--glow-ring),transparent 58%),var(--paper-2)}
  .cust-grid{display:grid;grid-template-columns:1fr 1fr;gap:44px;align-items:center}
  @media(max-width:820px){.cust-grid{grid-template-columns:1fr;gap:24px}}
  .customize-band h2{font-size:clamp(30px,4.4vw,46px);font-weight:300;margin:12px 0 16px}
  .customize-band p{color:var(--ink-2);font-size:16px;max-width:46ch;margin:0 0 24px}
  .combo-count{display:inline-flex;gap:8px;align-items:center;font-family:var(--mono);font-size:12px;color:var(--ink);
    border:1px solid var(--line-2);border-radius:999px;padding:6px 14px;margin-bottom:20px}
  .combo-count b{color:var(--glow)}
  .cust-preview{position:relative;display:flex;flex-direction:column;align-items:center;gap:10px}
  .cust-stage{width:100%;max-width:340px}
  .cust-stage .lamp{width:100%;aspect-ratio:5/7}

  /* The chosen lamp settles rather than bounces — a short rise and fall, so the
     eye registers that something changed without the control feeling springy. */
  .cust-stage.settle{animation:settle .5s ease}
  @keyframes settle{0%{transform:translateY(0) scale(1)}
    38%{transform:translateY(-5px) scale(1.02)}100%{transform:translateY(0) scale(1)}}

  /* ---------- the spool ----------
     Swatches sit on a cylinder: each rotateY(i*step) translateZ(R) inside a
     preserve-3d ring, and the ring counter-rotates so the active colour faces
     front. Tilted back slightly so you see the top of the drum, which is what
     makes it read as a spool rather than a flat carousel. */
  .spool{display:flex;align-items:center;justify-content:center;gap:14px;margin-top:2px}
  .spool-track{width:210px;height:132px;display:grid;place-items:center;
    perspective:760px;perspective-origin:50% 42%}
  /* Tilted back 24deg so the cylinder reads as an ellipse seen from slightly
     above — a turntable. Without the tilt, a 4-dot ring puts two swatches
     exactly edge-on and one directly behind, so only one colour is visible. */
  .spool-ring{position:relative;width:1px;height:1px;transform-style:preserve-3d;
    transform:rotateX(-24deg);transition:transform .55s cubic-bezier(.34,.01,.2,1)}
  .spool-dot{position:absolute;left:-19px;top:-19px;width:38px;height:38px;border-radius:50%;
    border:1px solid rgba(255,255,255,.22);cursor:pointer;padding:0;
    --r:74px;transform:rotateY(calc(var(--i) * var(--step))) translateZ(var(--r));
    box-shadow:0 6px 16px -6px rgba(0,0,0,.6);
    transition:transform .55s cubic-bezier(.34,.01,.2,1),opacity .45s ease,
      box-shadow .3s ease,border-color .3s ease}
  .spool-dot.is-on{border-color:var(--glow);box-shadow:0 0 0 3px var(--glow-ring),0 8px 20px -6px rgba(0,0,0,.7)}
  .spool-arrow{width:38px;height:38px;flex:none;border-radius:50%;border:1px solid var(--line-2);
    background:var(--card);color:var(--ink);font-size:19px;line-height:1;cursor:pointer;
    display:grid;place-items:center;transition:border-color .2s,color .2s,transform .15s}
  .spool-arrow:hover{border-color:var(--glow);color:var(--glow)}
  .spool-arrow:active{transform:scale(.94)}
  .spool-name{margin:0;font-family:var(--mono);font-size:12px;letter-spacing:.1em;
    text-transform:uppercase;color:var(--ink-2)}

  /* Lamp switcher: each lamp's own silhouette is the control. */
  .lamp-switch{display:flex;gap:10px;margin:0 0 22px}
  .lampchip{display:flex;flex-direction:column;align-items:center;gap:4px;width:66px;padding:8px 4px 6px;
    border:1px solid var(--line);border-radius:12px;background:var(--card);cursor:pointer;
    font-family:var(--mono);font-size:9.5px;letter-spacing:.08em;text-transform:uppercase;
    color:var(--ink-3);transition:border-color .25s,color .25s,transform .2s}
  .lampchip img{width:34px;height:44px;object-fit:contain;opacity:.72;transition:opacity .25s}
  .lampchip:hover{transform:translateY(-2px)}
  .lampchip.is-on{border-color:var(--glow);color:var(--ink)}
  .lampchip.is-on img{opacity:1}

  /* prefers-reduced-motion asks for less MOTION, not a different layout. A tilted
     3D ring that snaps instantly to its new position is not motion, so the spool
     keeps its arrangement and only loses the rotation transition and the settle.
     Flattening it entirely would mean anyone with the OS setting on never sees the
     control as designed. */
  @media(prefers-reduced-motion:reduce){
    .spool-ring,.spool-dot{transition:none}
    .cust-stage.settle{animation:none}
  }
  @media(max-width:520px){
    .spool-track{width:150px;height:92px}
    .spool-dot{--r:58px}
  }

  /* ---------- configurator (in detail modal) ---------- */
  .config{display:flex;flex-direction:column;gap:14px;width:100%}
  .cfg-stage{position:relative;perspective:1000px;display:grid;place-items:center;padding:6px 46px}
  .cfg-lamp3d{width:100%;max-width:380px;transform-style:preserve-3d;animation:drift 8s ease-in-out infinite}
  /* The detail panel is ~510x845, so a 1:1 stage against 2:3 art wasted most of it —
     the lamp rendered at 195x293 in a half-page panel. Same 5:7 stage the cards use. */
  .cfg-stage .lamp,.dvisual .dlampwrap .lamp{aspect-ratio:5/7}
  @keyframes drift{0%,100%{transform:rotateY(-8deg) rotateX(2deg)}50%{transform:rotateY(8deg) rotateX(2deg)}}
  .cfg-arrow{position:absolute;width:42px;height:42px;border-radius:50%;border:1px solid var(--line-2);background:var(--card);
    color:var(--ink);font-size:20px;line-height:1;cursor:pointer;display:grid;place-items:center;z-index:5;
    box-shadow:var(--shadow);transition:transform .15s,border-color .2s,color .2s}
  .cfg-arrow:hover{border-color:var(--glow);color:var(--glow);transform:scale(1.09)}
  .cfg-arrow:active{transform:scale(.96)}
  .cfg-arrow.t{top:20%}.cfg-arrow.b{bottom:16%}
  .cfg-arrow.l{left:0}.cfg-arrow.r{right:0}
  .cfg-labels{display:flex;justify-content:space-between;gap:14px;flex-wrap:wrap}
  .cfg-lbl{display:flex;align-items:center;gap:9px;font-family:var(--mono);font-size:12px;color:var(--ink-2);letter-spacing:.04em}
  .cfg-lbl .dot{width:16px;height:16px;border-radius:50%;border:1px solid rgba(120,120,120,.4);transition:background-color .45s ease}
  .cfg-lbl b{color:var(--ink);font-weight:400}
  .part-pop{animation:pop .5s ease}
  @keyframes pop{0%{transform:scale(1)}35%{transform:scale(1.07) translateY(-2px)}100%{transform:scale(1)}}

  /* gallery */
  .gallery{display:grid;grid-template-columns:repeat(4,1fr);grid-auto-rows:200px;gap:14px}
  .g-a{grid-column:span 2;grid-row:span 2}.g-b{grid-column:span 2}
  .g-tall{grid-column:span 1;grid-row:span 2}
  .g-c{grid-column:span 1}.g-d{grid-column:span 1}
  .gallery .imgslot .cap{position:absolute;left:14px;bottom:12px;z-index:2;font-family:var(--mono);font-size:11px;
    letter-spacing:.1em;text-transform:uppercase;color:#fff;text-shadow:0 1px 6px rgba(0,0,0,.6);opacity:0;transition:opacity .3s}
  .gallery .imgslot.filled:hover .cap{opacity:1}
  @media(max-width:720px){.gallery{grid-template-columns:1fr 1fr;grid-auto-rows:150px}.g-a{grid-column:span 2;grid-row:span 1}}

  /* process */
  .band{background:var(--paper-2);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
  .proc-grid{display:grid;grid-template-columns:1.1fr .9fr;gap:40px;align-items:center;margin-top:8px}
  @media(max-width:820px){.proc-grid{grid-template-columns:1fr;gap:24px}}
  .steps{display:grid;gap:22px}
  .step{border-top:1px solid var(--line-2);padding-top:16px}
  .step .n{font-family:var(--mono);font-size:12px;color:var(--glow);letter-spacing:.1em}
  .step h3{font-size:19px;margin:8px 0 6px;font-weight:400}
  .step p{color:var(--ink-2);font-size:14px;margin:0}
  .proc-media{position:relative}
  .proc-media .imgslot{aspect-ratio:4/5}
  .playtag{position:absolute;left:14px;top:14px;z-index:2;display:inline-flex;align-items:center;gap:8px;
    font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-2);
    background:var(--card);border:1px solid var(--line);border-radius:999px;padding:6px 12px}

  /* story */
  .story-grid{display:grid;grid-template-columns:1fr 1fr;gap:48px;align-items:center}
  @media(max-width:820px){.story-grid{grid-template-columns:1fr;gap:28px}}
  .story h2{font-size:clamp(26px,3.6vw,38px);font-weight:300;margin-bottom:18px}
  .story p{color:var(--ink-2);font-size:16px;max-width:52ch}
  .quote{font-family:var(--serif);font-style:italic;font-size:clamp(22px,3vw,30px);line-height:1.35;color:var(--ink);margin-top:22px}
  .quote span{color:var(--glow)}
  .story .imgslot{aspect-ratio:4/5}

  /* reviews */
  .reviews{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
  @media(max-width:760px){.reviews{grid-template-columns:1fr}}
  .review{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:24px;box-shadow:var(--shadow)}
  .stars{color:var(--glow);letter-spacing:2px;font-size:14px;margin-bottom:12px}
  .review p{margin:0 0 16px;font-size:15px;color:var(--ink)}
  .review .who{font-family:var(--mono);font-size:12px;color:var(--ink-3);letter-spacing:.04em}

  /* faq */
  .faq{max-width:820px;margin:0 auto}
  .qa{border-bottom:1px solid var(--line)}
  .qa button{width:100%;text-align:left;background:none;border:none;color:var(--ink);cursor:pointer;
    padding:20px 4px;font-family:var(--sans);font-size:17px;display:flex;justify-content:space-between;align-items:center;gap:16px}
  .qa .plus{font-family:var(--mono);color:var(--ink-3);flex:none;transition:transform .3s}
  .qa button[aria-expanded="true"] .plus{transform:rotate(45deg);color:var(--glow)}
  .qa .a{max-height:0;overflow:hidden;transition:max-height .35s ease}
  .qa .a p{color:var(--ink-2);font-size:14.5px;margin:0 0 20px;padding-right:30px;max-width:64ch}

  /* newsletter */
  .signup{background:var(--ink);color:var(--paper);border-radius:22px;padding:clamp(28px,5vw,56px);
    display:grid;grid-template-columns:1.1fr .9fr;gap:32px;align-items:center}
  .signup h2{font-size:clamp(26px,3.6vw,40px);font-weight:300;color:var(--paper)}
  .signup p{color:color-mix(in srgb,var(--paper) 70%,transparent);margin:14px 0 0;max-width:40ch}
  .form{display:flex;gap:10px;flex-wrap:wrap}
  .form input{flex:1;min-width:200px;height:52px;border-radius:999px;border:1px solid rgba(255,255,255,.2);
    background:rgba(255,255,255,.06);color:var(--paper);padding:0 20px;font-size:15px;font-family:var(--sans)}
  .form input::placeholder{color:rgba(255,255,255,.5)}
  .form button{height:52px;padding:0 26px;border-radius:999px;border:none;background:var(--glow);color:#241200;
    font-size:15px;cursor:pointer;font-weight:500;transition:transform .15s}
  .form button:hover{transform:translateY(-1px)}
  .form .note{font-family:var(--mono);font-size:11px;color:color-mix(in srgb,var(--paper) 55%,transparent);width:100%}
  .form .hp{position:absolute;left:-9999px;width:1px;height:1px;opacity:0}
  .form button[disabled]{opacity:.6;cursor:default;transform:none}
  @media(max-width:720px){.signup{grid-template-columns:1fr}}

  /* footer */
  footer{border-top:1px solid var(--line);padding:52px 0 60px;color:var(--ink-2);font-size:13.5px}
  .foot-top{display:grid;grid-template-columns:1.4fr 1fr 1fr;gap:30px;margin-bottom:40px}
  @media(max-width:680px){.foot-top{grid-template-columns:1fr}}
  .foot-col h4{font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);margin:0 0 14px;font-weight:400}
  .foot-col a{display:block;padding:5px 0;color:var(--ink-2);transition:color .2s}
  .foot-col a:hover{color:var(--ink)}
  .foot-brand .brand{font-size:24px;margin-bottom:10px}
  .foot-brand p{max-width:34ch;color:var(--ink-2);margin:0}
  .foot-bottom{display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap;align-items:center;
    border-top:1px solid var(--line);padding-top:22px;font-family:var(--mono);font-size:11.5px;letter-spacing:.04em;color:var(--ink-3)}

  /* overlays */
  .scrim{position:fixed;inset:0;background:rgba(10,8,4,.5);backdrop-filter:blur(3px);opacity:0;visibility:hidden;transition:opacity .3s;z-index:var(--z-scrim)}
  .scrim.open{opacity:1;visibility:visible}
  .drawer{position:fixed;top:0;right:0;height:100%;width:min(400px,92vw);z-index:var(--z-drawer);background:var(--paper);
    border-left:1px solid var(--line);transform:translateX(100%);transition:transform .38s cubic-bezier(.4,0,.1,1);display:flex;flex-direction:column}
  .drawer.open{transform:translateX(0)}
  .drawer .dhead{display:flex;justify-content:space-between;align-items:center;padding:22px 22px 16px;border-bottom:1px solid var(--line)}
  .drawer .dhead h3{font-size:16px;font-family:var(--mono);letter-spacing:.1em;text-transform:uppercase}
  .drawer .items{flex:1;overflow-y:auto;padding:8px 22px}
  .citem{display:flex;gap:14px;padding:16px 0;border-bottom:1px solid var(--line);align-items:center}
  .citem .mini{width:52px;height:52px;border-radius:8px;background:var(--paper-2);display:grid;place-items:center;flex:none;overflow:hidden}
  .citem .mini .dot{width:22px;height:30px;border-radius:8px 8px 3px 3px;background:linear-gradient(var(--glow-2),var(--glow))}
  .citem .cn{flex:1}.citem .cn b{font-weight:400;font-size:15px}
  .citem .cn small{color:var(--ink-3);font-family:var(--mono)}
  .citem .cp{font-family:var(--mono);font-variant-numeric:tabular-nums}
  .qty{display:flex;align-items:center;gap:10px;margin-top:4px;font-family:var(--mono);font-size:13px}
  .qty button{width:24px;height:24px;border-radius:6px;border:1px solid var(--line-2);background:transparent;color:var(--ink);cursor:pointer;line-height:1}
  .empty{color:var(--ink-3);text-align:center;padding:60px 20px;font-family:var(--mono);font-size:13px}
  .dfoot{padding:20px 22px;border-top:1px solid var(--line)}
  .dfoot .line{display:flex;justify-content:space-between;margin-bottom:6px;font-size:14px;color:var(--ink-2)}
  .dfoot .total{color:var(--ink);font-size:18px;font-family:var(--mono);font-variant-numeric:tabular-nums}
  .dfoot .btn{width:100%;justify-content:center;margin-top:12px}
  .dfoot .fineprint{font-family:var(--mono);font-size:10.5px;color:var(--ink-3);text-align:center;margin-top:10px;letter-spacing:.04em}

  .detail{position:fixed;inset:0;z-index:var(--z-detail);display:flex;pointer-events:none}
  .detail .panel{margin:auto;width:min(1000px,96vw);max-height:94vh;overflow-y:auto;background:var(--paper);
    border:1px solid var(--line);border-radius:20px;transform:translateY(24px) scale(.98);opacity:0;
    transition:transform .34s cubic-bezier(.4,0,.1,1),opacity .3s;box-shadow:0 30px 80px -30px rgba(0,0,0,.5);position:relative}
  .detail.open{pointer-events:auto}.detail.open .panel{transform:none;opacity:1}
  .dgrid{display:grid;grid-template-columns:1.05fr 1fr}
  @media(max-width:780px){.dgrid{grid-template-columns:1fr}}
  .dvisual{position:relative;background:radial-gradient(75% 65% at 50% 42%,var(--paper-2),transparent 80%);
    padding:28px;display:flex;flex-direction:column;justify-content:center;border-right:1px solid var(--line)}
  @media(max-width:780px){.dvisual{border-right:none;border-bottom:1px solid var(--line)}}
  .dvisual .dlampwrap .lamp{max-width:400px;margin:auto;width:100%}
  .switch{display:flex;align-items:center;gap:12px;justify-content:center;margin-top:8px}
  .switch span{font-family:var(--mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3)}
  .toggle{position:relative;width:56px;height:30px;border-radius:999px;border:1px solid var(--line-2);background:var(--paper);
    cursor:pointer;transition:background .3s,border-color .3s;flex:none}
  .toggle::after{content:"";position:absolute;top:3px;left:3px;width:22px;height:22px;border-radius:50%;background:var(--ink-3);transition:transform .3s,background .3s}
  .toggle[aria-pressed="true"]{background:var(--glow-ring);border-color:var(--glow)}
  .toggle[aria-pressed="true"]::after{transform:translateX(26px);background:var(--glow)}
  .dinfo{padding:30px 30px 34px;display:flex;flex-direction:column;gap:2px}
  .dclose{position:absolute;top:14px;right:14px;z-index:3}
  .dinfo .price{font-family:var(--mono);font-size:20px;font-variant-numeric:tabular-nums;margin-top:2px}
  .dinfo h2{font-size:34px;font-weight:300;letter-spacing:-.03em}
  .dinfo .long{color:var(--ink-2);font-size:15px;margin:14px 0 6px;max-width:46ch}
  .spectable{border-top:1px solid var(--line);margin-top:14px}
  .spectable .r{display:flex;justify-content:space-between;padding:11px 0;border-bottom:1px solid var(--line);font-family:var(--mono);font-size:12.5px}
  .spectable .r span:first-child{color:var(--ink-3);letter-spacing:.06em;text-transform:uppercase;font-size:11px}
  .spectable .r span:last-child{color:var(--ink);font-variant-numeric:tabular-nums}
  .scale{margin:20px 0 6px}
  .scale .lbl{font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);margin-bottom:10px}
  .scalebar{display:flex;align-items:center;gap:12px;margin-bottom:8px}
  .scalebar .sn{font-family:var(--mono);font-size:11px;color:var(--ink-2);width:96px;flex:none}
  .scalebar .track{flex:1;height:10px;background:var(--paper-2);border:1px solid var(--line);border-radius:999px;overflow:hidden}
  .scalebar .fill{display:block;height:100%;border-radius:999px;background:var(--line-2)}
  .scalebar.me .fill{background:linear-gradient(90deg,var(--glow),var(--glow-2))}
  .scalebar .sv{font-family:var(--mono);font-size:11px;color:var(--ink-3);width:56px;text-align:right;flex:none}
  .dinfo .buy{display:flex;gap:10px;margin-top:22px;align-items:center;flex-wrap:wrap}
  .dinfo .buy .btn{flex:1;justify-content:center;min-width:180px}

  /* ---------- product page (Task 15) ---------- */
  .crumbs{padding:20px 24px 0;font-family:var(--mono);font-size:11px;letter-spacing:.1em;
    text-transform:uppercase;color:var(--ink-3)}
  .crumbs a:hover{color:var(--ink)}
  .pdp{padding:28px 0 64px}
  .pdp-grid{display:grid;grid-template-columns:1.05fr .95fr;gap:48px;align-items:center}
  @media(max-width:860px){.pdp-grid{grid-template-columns:1fr;gap:24px}}
  .pdp-visual{position:relative;background:radial-gradient(75% 65% at 50% 42%,var(--paper-2),transparent 80%);
    border-radius:20px;padding:24px}
  .pdp-info h1{font-size:clamp(32px,5vw,46px);font-weight:300;letter-spacing:-.03em;margin:6px 0 4px}
  .pdp-price{font-family:var(--mono);font-size:22px;font-variant-numeric:tabular-nums;margin:0}
  /* Same layout as the detail modal's .dinfo .buy, scoped to the product
     page's own info column instead — the modal and the page share every
     other buy/spec/scale rule (bare selectors below), just not this one. */
  .pdp-info .buy{display:flex;gap:10px;margin-top:22px;align-items:center;flex-wrap:wrap}
  .pdp-info .buy .btn{flex:1;justify-content:center;min-width:180px}
  .pdp-missing{text-align:center;padding:60px 0}
  .pdp-missing h1{font-size:32px;font-weight:300;margin-bottom:10px}
  .pdp-more-h{font-size:22px;font-weight:300;margin:0 0 20px}

  .reveal{opacity:0;transform:translateY(18px);transition:opacity .7s ease,transform .7s ease}
  .reveal.in{opacity:1;transform:none}
  @media(prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}.reveal{opacity:1;transform:none}
    .cfg-lamp3d{transform:rotateY(-6deg) rotateX(2deg)}}

  /* ---------- video slot (process timelapse) ---------- */
  .imgslot.is-video video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
  .imgslot .vidplay{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:3;
    width:56px;height:56px;border-radius:50%;border:1px solid rgba(255,255,255,.35);
    background:rgba(20,16,10,.5);backdrop-filter:blur(6px);color:#fff;font-size:17px;
    cursor:pointer;display:grid;place-items:center;transition:opacity .3s,transform .15s}
  .imgslot .vidplay:hover{transform:translate(-50%,-50%) scale(1.06)}
  .imgslot.playing .vidplay{opacity:0;pointer-events:none}
  .imgslot.is-video:hover .vidplay{opacity:1;pointer-events:auto}
  .imgslot.filled .cap{opacity:1}

  /* ---------- touch targets & phone type ----------
     Audited at 360/390/430/768 with is_mobile+has_touch: the three header
     .iconbtns and the spool / configurator arrows all measured under 44px, which
     is the minimum comfortable touch target. The spool swatches keep their 38px
     visual size — inflating them would crowd the ring — and gain the extra hit
     area through a transparent ::after instead. */
  @media (hover:none),(max-width:680px){
    .iconbtn{min-height:44px;min-width:44px}
    .spool-arrow,.cfg-arrow{width:44px;height:44px;font-size:21px}
    .spool-dot::after{content:"";position:absolute;inset:-8px}
    .qty button{min-width:36px;min-height:36px}
    .dclose{min-width:44px;min-height:44px}
    .toggle{height:44px;width:76px}
    .toggle::after{width:36px;height:36px}
    .toggle[aria-pressed="true"]::after{transform:translateX(32px)}
  }
  /* 11px mono is legible on a desktop at arm's length and cramped on a phone. */
  @media(max-width:820px){
    .specs{font-size:12px}
    .card .blurb{font-size:14.5px}
    .imgslot .ph .t{font-size:12px}
    .imgslot .ph .s{font-size:11px}
    .spool-name,.review .who{font-size:12px}
  }

  /* Cart line thumbnail: the actual lamp and colorway chosen, not a generic swatch. */
  .citem .mini{background:var(--paper-2);border:1px solid var(--line)}
  .citem .mini img{width:100%;height:100%;object-fit:contain;padding:2px}
