/* /20 content sections: they scroll up over the fixed scene (spheres + network), in eeee.mu's type (Inter 300 + Space Mono). */
.p20{position:relative;z-index:4;background:rgba(8,8,8,.94);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);
  border-top:1px solid rgba(255,255,255,.08);padding:0 clamp(16px,4vw,64px)}
.p20-sec{max-width:1180px;margin:0 auto;padding:clamp(56px,9vw,112px) 0;border-bottom:1px solid rgba(255,255,255,.06)}
.p20-kick{font-family:var(--mono);font-size:11px;letter-spacing:.18em;text-transform:lowercase;color:var(--red);margin-bottom:18px}
.p20-h{font-family:var(--sans);font-weight:300;font-size:clamp(34px,6vw,76px);letter-spacing:-.02em;line-height:1.02;color:var(--ink);margin-bottom:clamp(24px,4vw,44px)}
.p20 p{font-size:clamp(15px,1.4vw,18px);line-height:1.7;color:#c9c9c4;font-weight:300}
.p20 p b{color:var(--ink);font-weight:500}
.p20 .r{color:var(--red)}
.p20-cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:clamp(20px,3vw,44px);align-items:start}
.p20-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:12px}
.p20-card,.p20-pass{display:flex;flex-direction:column;gap:8px;padding:22px;border:1px solid rgba(255,255,255,.1);border-radius:14px;background:rgba(255,255,255,.02)}
.p20-card b,.p20-pass b{font-weight:400;font-size:clamp(20px,2vw,26px);letter-spacing:-.01em;color:var(--ink)}
.p20-lbl{font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:lowercase;color:var(--dim)}
.p20-count b{color:var(--red);font-variant-numeric:tabular-nums;font-family:var(--mono);font-size:clamp(18px,1.8vw,22px)}
.p20-count span:last-child{font-family:var(--mono);font-size:11px;color:var(--dim)}
.tbc{font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:lowercase;color:#6d6a63;border:1px dashed #3a3a38;border-radius:6px;padding:3px 8px;align-self:flex-start}
.tbc-line{margin:6px 0 18px}
.p20-pass{text-decoration:none;transition:border-color .2s,transform .2s}
.p20-pass:hover,.p20-pass:focus-visible{border-color:var(--red);transform:translateY(-2px);outline:none}
.p20-pass.is-main{border-color:rgba(255,59,48,.5);background:rgba(255,59,48,.05)}
.p20-go{margin-top:auto;padding-top:10px;font-family:var(--mono);font-size:11px;letter-spacing:.1em;color:var(--red)}
.p20-note{font-family:var(--mono);font-size:11px !important;color:var(--dim) !important;margin-top:14px}
.p20-codes{display:grid;gap:10px}
.p20-codes div{display:flex;justify-content:space-between;align-items:baseline;padding:14px 18px;border:1px solid rgba(255,255,255,.1);border-radius:12px}
.p20-codes b{font-family:var(--mono);font-weight:700;letter-spacing:.08em;color:var(--red)}
.p20-cta{display:inline-flex;margin-top:clamp(28px,4vw,44px);padding:16px 26px;border-radius:14px;background:var(--red);color:#141413;text-decoration:none;
  font-family:var(--mono);font-weight:700;font-size:13px;letter-spacing:.12em;text-transform:uppercase;box-shadow:0 6px 0 #9e1c14,0 10px 24px -8px rgba(255,59,48,.6)}
.p20-cta:active{transform:translateY(5px);box-shadow:0 1px 0 #9e1c14}
.p20-link{font-family:var(--mono);font-size:12px;letter-spacing:.08em;color:var(--ink);text-decoration:none;border-bottom:1px solid var(--red)}
.p20-links{display:grid;border-top:1px solid rgba(255,255,255,.08)}
.p20-links a{display:flex;justify-content:space-between;gap:16px;padding:18px 0;border-bottom:1px solid rgba(255,255,255,.08);color:var(--ink);text-decoration:none;
  font-weight:300;font-size:clamp(20px,2.4vw,30px);letter-spacing:-.01em}
.p20-links a span{font-family:var(--mono);font-size:11px;letter-spacing:.08em;color:var(--dim);align-self:center}
.p20-links a:hover span,.p20-links a:hover{color:var(--red)}
.p20-legal{max-width:1180px;margin:0 auto;padding:28px 0 40px;font-family:var(--mono);font-size:11px !important;color:var(--dim) !important}
.p20-legal a{color:var(--ink);text-decoration:none;border-bottom:1px solid #3a3a38}
.p20 .e{display:inline-block}
.site-footer{z-index:4}
/* ë with two red dots: the e is the normal glyph (AV 27 Sep: no mirror); the two dots are drawn, red, never the font's diaeresis */
.e.ed{position:relative}
.e.ed::after{content:"";position:absolute;left:calc(50% - .2em);top:.17em;width:.13em;height:.13em;border-radius:50%;background:var(--red,#ff3b30);box-shadow:.27em 0 0 var(--red,#ff3b30)}
/* ?mark=dots: the written "20" steps back (kept for screen readers via its aria-label); the dots say it */
.mark-dots h1.twenty{opacity:0 !important}

/* ---------- CLEAN pass (AV "make it clean"): no boxes, no dashed chips, hairlines only ---------- */
.tbc{border:0;padding:0;border-radius:0;color:#5f5c56;letter-spacing:.14em}
.tbc-line{margin:0 0 14px}
.p20-grid{gap:0;border-top:1px solid rgba(255,255,255,.08)}
.p20-card,.p20-pass{border:0;border-bottom:1px solid rgba(255,255,255,.08);border-radius:0;background:none;padding:22px 0;gap:6px}
.p20-grid{grid-template-columns:repeat(auto-fit,minmax(220px,1fr));column-gap:clamp(20px,3vw,44px)}
.p20-pass.is-main{background:none;border-color:rgba(255,255,255,.08)}
.p20-pass.is-main b{color:var(--red)}
.p20-pass:hover,.p20-pass:focus-visible{transform:none;border-color:var(--red)}
.p20-codes div{border:0;border-bottom:1px solid rgba(255,255,255,.08);border-radius:0;padding:12px 0}
.p20-sec{border-bottom:0;padding:clamp(48px,8vw,96px) 0}
.p20-h{margin-bottom:clamp(18px,3vw,32px)}

/* ---------- PHONE = THE APP (AV: "can the mobile app fill the screen"): the device IS the screen.
   Its black screen is a window onto the live scene (dots, 20, particles); hardware below; logo + menu inside the screen. ---------- */
@media (max-width:760px){
  .hero{height:100svh;min-height:100svh;padding:0;display:block}
  .hero .d20{position:absolute;inset:0;width:auto;transform:none;border-radius:0;display:flex;flex-direction:column;
    padding:10px 10px calc(10px + env(safe-area-inset-bottom));background:transparent;box-shadow:none;overflow:hidden}
  .hero .d20 .d20-lcd{flex:1;min-height:0;background:transparent;justify-content:flex-end;border-radius:30px;pointer-events:none;
    box-shadow:0 0 0 40px var(--bezel,#d4d0c8),inset 0 0 0 1px rgba(255,255,255,.06)}   /* the cream bezel around a see-through screen */
  .hero .d20 .d20-body a{pointer-events:auto}
  .hero .d20 .d20-body{flex:none !important}
  .hero .d20 .d20-body{background:linear-gradient(transparent,rgba(0,0,0,.72) 30%);margin:0 -14px -10px;padding:26px 14px 8px;border-radius:0 0 30px 30px}
  .hero .d20 .d20-top{position:absolute;left:0;right:0;opacity:0}
  .hero .d20 .d20-dots{padding-bottom:4px}
  .hero .d20 .d20-hw{position:relative;background:linear-gradient(180deg,rgba(255,255,255,.3),rgba(255,255,255,0) 20%),var(--grain) 0 0/240px 240px,linear-gradient(180deg,#d4d0c8,#c6c2b9);background-blend-mode:normal,soft-light,normal;margin:0 -10px calc(-10px - env(safe-area-inset-bottom));
    padding:14px 14px calc(14px + env(safe-area-inset-bottom))}
  .hero .d20 .d20-grille{aspect-ratio:2.4}
  .hero .d20 .d20-grille svg{width:44%}
  .hero .d20 .d20-dial{width:62px;height:62px}
  .hero-head{top:78px;z-index:4}
  .site-logo,.header-actions{top:22px}
}

@media (max-width:760px){
  html[data-finish=dark] .hero .d20{--bezel:#222224}
  html[data-finish=dark] .hero .d20 .d20-hw{background:linear-gradient(180deg,rgba(255,255,255,.06),rgba(255,255,255,0) 20%),var(--grain) 0 0/240px 240px,linear-gradient(180deg,#29292c,#1b1b1d);background-blend-mode:normal,overlay,normal}
}
@media (max-width:760px){   /* compact hardware so the screen stays big */
  .hero .d20 .d20-row{grid-template-columns:1.6fr 1fr;gap:8px}
  .hero .d20 .d20-grille{aspect-ratio:3.4}
  .hero .d20 .d20-grille svg{width:26%}
  .hero .d20 .d20-dial{width:48px;height:48px}
  .hero .d20 .d20-arrows button{height:22px;width:30px}
  .hero .d20 .d20-hw{gap:8px;padding-top:10px}
  .hero .d20 .d20-pad{aspect-ratio:2.5;padding:6px 8px}
  .hero .d20 .d20-led{top:6px;left:8px}
  .hero .d20 .d20-pass button{height:28px}
  .hero .d20 .d20-key{padding:10px 10px 9px}
}
/* ---------- BOOT: loads like a game (AV). One tap = sound + tilt permission + start ---------- */
.boot{position:fixed;inset:0;z-index:10000;background:#050505;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:26px;
  font-family:var(--mono);color:#ededea;cursor:pointer;transition:clip-path .7s cubic-bezier(.9,0,.1,1);clip-path:inset(0)}
.boot.out{clip-path:inset(50% 0 50% 0)}
.boot-dots{display:flex;gap:28px}
.boot-dots i{width:64px;height:64px;border-radius:50%;background:radial-gradient(circle,#ff2115 60%,rgba(255,33,21,.25) 70%,transparent 74%);animation:bootpulse 1.6s ease-in-out infinite}
.boot-dots i+i{animation-delay:.2s}
@keyframes bootpulse{50%{transform:scale(.9)}}
.boot-tap{font-size:12px;letter-spacing:.3em;text-transform:uppercase;animation:blink 1.1s steps(2,start) infinite}
@keyframes blink{to{visibility:hidden}}
.boot-count{font-size:11px;letter-spacing:.2em;color:#6d6a63;font-variant-numeric:tabular-nums}
.boot.loading .boot-tap{animation:none}

/* codegrid motion layer (cg.js) · only styles what the script adds */
.cg-on .p20-sec{position:relative}
.cg-line{position:absolute;left:0;right:0;top:0;height:1px;background:linear-gradient(90deg,var(--red),rgba(255,255,255,.12) 40%,transparent);transform-origin:0 50%;pointer-events:none}
.cg-m{display:inline-block;overflow:hidden;vertical-align:top;padding-bottom:.08em;margin-bottom:-.08em}
.cg-w{display:inline-block;will-change:transform}
.cg-roll{display:inline-grid;overflow:hidden;line-height:1.2;vertical-align:top}
.cg-roll>span{grid-area:1/1;transition:transform .55s cubic-bezier(.8,0,.1,1)}
.cg-roll>span+span{transform:translateY(105%)}
a:hover>.cg-roll>span:first-child,.p20-pass:hover .cg-roll>span:first-child,a:focus-visible>.cg-roll>span:first-child{transform:translateY(-105%)}
a:hover>.cg-roll>span+span,.p20-pass:hover .cg-roll>span+span,a:focus-visible>.cg-roll>span+span{transform:translateY(0)}

/* ---------- MATERIAL v2 · brushed plastic under ONE moving light (AV, 27 Sep: "realistic plastic finish, brushed",
   "like on iphone, shadows move with the phone"). --lx/--ly (-1..1) come from e-motion.js: phone tilt, or the mouse.
   brush = long horizontal streaks (fractal noise stretched along x) · grain = fine moulding texture ·
   sheen = the anisotropic highlight a brushed surface throws, sliding across as the light moves · shadows fall opposite the light. */
.d20.d20--classic,.hero .d20.d20--classic .d20-hw{
  --brush:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='600' height='180'%3E%3Cfilter id='b'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.0035 .95' numOctaves='4' seed='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .5  0 0 0 0 .5  0 0 0 0 .5  0 0 0 .9 0'/%3E%3CfeComponentTransfer%3E%3CfeFuncR type='linear' slope='2.2' intercept='-.6'/%3E%3CfeFuncG type='linear' slope='2.2' intercept='-.6'/%3E%3CfeFuncB type='linear' slope='2.2' intercept='-.6'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23b)'/%3E%3C/svg%3E");
  --grain2:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' seed='9' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .5  0 0 0 0 .5  0 0 0 0 .5  0 0 0 .5 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
  --sx:calc(50% - var(--lx,0)*45%);
  --lightpos:calc(50% + var(--lx,0)*45%) calc(var(--ly,0)*35%);
  background:
    linear-gradient(100deg,transparent 34%,rgba(255,255,255,.5) 50%,transparent 66%) var(--sx) 0/320% 100% no-repeat,
    radial-gradient(120% 70% at var(--lightpos),rgba(255,255,255,.4),transparent 58%),
    linear-gradient(180deg,rgba(255,255,255,.22),transparent 14%,transparent 86%,rgba(0,0,0,.14)),
    var(--brush) 0 0/600px 180px,
    var(--grain2) 0 0/180px 180px,
    linear-gradient(180deg,#dcd9d2,#c5c1b8);
  background-blend-mode:normal,normal,normal,overlay,soft-light,normal;
}
.d20.d20--classic{
  box-shadow:calc(var(--lx,0)*-24px) calc(34px + var(--ly,0)*-24px) 70px -24px rgba(0,0,0,.75),
    inset 0 1px 0 rgba(255,255,255,.75),inset 0 -2px 0 rgba(0,0,0,.2),
    inset calc(var(--lx,0)*-3px) calc(var(--ly,0)*-3px) 0 rgba(0,0,0,.05);
}
html[data-finish=dark] .d20.d20--classic,html[data-finish=dark] .hero .d20.d20--classic .d20-hw{
  background:
    linear-gradient(100deg,transparent 38%,rgba(255,255,255,.08) 50%,transparent 62%) var(--sx) 0/320% 100% no-repeat,
    radial-gradient(120% 70% at var(--lightpos),rgba(255,255,255,.07),transparent 62%),
    linear-gradient(180deg,rgba(255,255,255,.06),transparent 14%,transparent 86%,rgba(0,0,0,.35)),
    var(--brush) 0 0/600px 180px,
    var(--grain2) 0 0/180px 180px,
    linear-gradient(180deg,#2c2c2f,#1b1b1d);
  background-blend-mode:normal,normal,normal,overlay,soft-light,normal;
}
html[data-finish=dark] .d20.d20--classic{
  box-shadow:calc(var(--lx,0)*-24px) calc(34px + var(--ly,0)*-24px) 70px -24px rgba(0,0,0,.9),
    inset 0 1px 0 rgba(255,255,255,.1),inset 0 -2px 0 rgba(0,0,0,.5)}
/* every part casts a shadow away from the light */
.d20.d20--classic :is(.d20-pad,.d20-key,.d20-dial,.d20-arrows button){
  filter:drop-shadow(calc(var(--lx,0)*-7px) calc(4px + var(--ly,0)*-7px) 5px rgba(0,0,0,.34))}
/* the knob's highlight turns toward the light */
.d20.d20--classic .d20-dial{background:radial-gradient(circle at calc(35% + var(--lx,0)*30%) calc(30% + var(--ly,0)*30%),#5a5a58,#141413 68%)}
html[data-finish=dark] .d20.d20--classic .d20-dial{background:radial-gradient(circle at calc(35% + var(--lx,0)*22%) calc(30% + var(--ly,0)*22%),#f8f6f0,#bdb9b0 70%)}
/* the screen is recessed: its inner shadow sits on the side facing the light */
.d20.d20--classic .d20-lcd{box-shadow:inset calc(var(--lx,0)*-5px) calc(3px + var(--ly,0)*-5px) 10px rgba(0,0,0,.85),0 1px 0 rgba(255,255,255,.35)}
@media (prefers-reduced-motion:reduce){.d20.d20--classic{--lx:0;--ly:0}}
/* phone fix (27 Sep): the material v2 body texture must not cover the see-through screen. On phones the device IS the app:
   the body stays transparent (the live scene shows through the screen); only the hardware panel gets the brushed plastic. */
@media (max-width:760px){
  .hero .d20.d20--classic,html[data-finish=dark] .hero .d20.d20--classic{background:transparent;box-shadow:none}
}
