:root{--bg:#f7f0e8;--card:#fffaf5;--skin:#ecd3c0;--accent:#c47a5a;--ink:#3a2e29;--muted:#7d6b62;--line:#eadccf}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{background:var(--bg);color:var(--ink);font:17px/1.65 system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;-webkit-font-smoothing:antialiased;overflow-x:hidden}
body::before{content:"";position:fixed;inset:0;z-index:-1;background:
 radial-gradient(600px 400px at 85% -5%,#f0d5c3 0%,transparent 70%),
 radial-gradient(500px 500px at -5% 60%,#f3e2d3 0%,transparent 70%)}
.wrap{max-width:980px;margin:0 auto;padding:0 24px}
nav{display:flex;justify-content:space-between;align-items:center;padding:28px 0}
nav .logo{font-weight:700;letter-spacing:-.02em}
nav a{color:var(--muted);text-decoration:none;margin-left:24px;font-size:15px;transition:color .2s}
nav a:hover{color:var(--accent)}
.hero{padding:90px 0 70px}
.pill{display:inline-block;background:var(--skin);color:#7a4a35;padding:6px 14px;border-radius:99px;font-size:14px;font-weight:600;margin-bottom:24px}
h1{font-size:clamp(2.6rem,7vw,4.6rem);line-height:1.05;letter-spacing:-.035em;max-width:14ch}
h1 .hl{color:var(--accent)}
.lead{color:var(--muted);font-size:1.2rem;max-width:52ch;margin:26px 0 34px}
.btn{display:inline-block;padding:13px 24px;border-radius:14px;font-weight:600;text-decoration:none;font-size:15px;transition:transform .2s,box-shadow .2s}
.btn:hover{transform:translateY(-2px)}
.btn.main{background:var(--ink);color:#fff8f2;box-shadow:0 8px 20px -8px rgba(58,46,41,.5)}
.btn.soft{background:var(--skin);color:#6b3f2c;margin-left:10px}
section{padding:50px 0}
h2{font-size:1.9rem;letter-spacing:-.02em;margin-bottom:8px}
.sub{color:var(--muted);margin-bottom:30px}
.card{background:var(--card);border:1px solid var(--line);border-radius:24px;padding:28px;box-shadow:0 14px 34px -22px rgba(120,80,55,.35);transition:transform .25s,box-shadow .25s}
.card:hover{transform:translateY(-4px);box-shadow:0 22px 40px -22px rgba(120,80,55,.45)}
.card h3{font-size:1.3rem;margin-bottom:8px;letter-spacing:-.01em}
.card p{color:var(--muted);font-size:16px;margin-bottom:16px}
.tags{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:18px}
.tags span{background:var(--bg);border:1px solid var(--line);border-radius:99px;padding:3px 12px;font-size:13px;color:#8a6650}
.card a{color:var(--accent);font-weight:600;text-decoration:none;margin-right:16px;font-size:15px}
.card .note{font-size:13px;color:var(--muted);margin-top:14px;margin-bottom:0}
.card .btn{padding:9px 18px;font-size:14px;margin-right:12px}
.demo{background:var(--bg);border-radius:12px;padding:10px 14px;font-size:14px;margin-bottom:16px;color:#6b5548}
.demo code{font-family:ui-monospace,Menlo,monospace}
.about{display:grid;gap:30px;grid-template-columns:1.3fr 1fr}
.stack{display:flex;flex-wrap:wrap;gap:10px;align-content:flex-start}
.stack span{background:var(--skin);color:#6b3f2c;padding:8px 16px;border-radius:14px;font-size:15px;font-weight:500}
.contact{text-align:center;background:var(--skin);border-radius:32px;padding:60px 24px;margin:40px 0 20px}
.contact h2{margin-bottom:12px}
.contact p{color:#7a5a48;margin-bottom:26px}
footer{text-align:center;color:var(--muted);font-size:14px;padding:30px 0 50px}
@keyframes up{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}
@media(max-width:700px){.about{grid-template-columns:1fr}.btn.soft{margin:12px 0 0}nav a{margin-left:14px}}
@media(prefers-reduced-motion:reduce){.card,.btn{animation:none;transition:none}}

/* ---- Baby blue accent (motion-upgrade, phase 1). Added on top of the palette above, never replacing it. ---- */
:root{--blue:#89cff0;--blue-soft:#bfe3f7;--blue-strong:#5bb4e0;--blue-text:#1f6f9f;--on-blue:var(--ink)}
::selection{background:var(--blue);color:var(--on-blue)}
:focus-visible{outline:2px solid var(--ink);outline-offset:3px;box-shadow:0 0 0 7px var(--blue-soft);border-radius:4px}
.btn:focus-visible{border-radius:14px}
.hero .btn.main,.card .btn.main{background:var(--blue);color:var(--on-blue);box-shadow:0 8px 20px -10px rgba(31,111,159,.55);transition:transform .2s,box-shadow .2s,background-color .2s}
.hero .btn.main:hover,.card .btn.main:hover{box-shadow:0 12px 24px -10px rgba(31,111,159,.6)}
.hero .btn.main:active,.card .btn.main:active{background:var(--blue-strong);transform:none}
.hero .btn.soft{background:transparent;color:var(--ink);box-shadow:inset 0 0 0 1.5px var(--ink);transition:transform .2s,background-color .2s}
.hero .btn.soft:hover{background:var(--blue-soft)}
.contact .btn.soft{transition:transform .2s,background-color .2s}
.contact .btn.soft:hover{background:var(--blue-soft)}
.pill{display:inline-flex;align-items:center;gap:8px}
.pill::before{content:"";width:8px;height:8px;border-radius:50%;background:var(--blue);box-shadow:0 0 0 1px rgba(31,111,159,.35);animation:pulse 2.4s ease-in-out infinite}
@keyframes pulse{0%,100%{box-shadow:0 0 0 1px rgba(31,111,159,.35),0 0 0 0 rgba(137,207,240,.7)}60%{box-shadow:0 0 0 1px rgba(31,111,159,.35),0 0 0 7px rgba(137,207,240,0)}}
nav a,.card a:not(.btn){background:linear-gradient(var(--blue-text),var(--blue-text)) no-repeat 0 100%/0 1.5px;transition:color .2s,background-size .3s var(--ease-out)}
nav a:hover{color:var(--ink);background-size:100% 1.5px}
.card a:not(.btn):hover{text-decoration:none;background-size:100% 1.5px}
.tags span,.stack span{transition:background-color .2s,border-color .2s}
.tags span:hover{background:var(--blue-soft);border-color:var(--blue-soft);color:var(--on-blue)}
.stack span:hover{background:var(--blue-soft);color:var(--on-blue)}
@media(prefers-reduced-motion:reduce){.pill::before{animation:none}nav a,.card a:not(.btn),.tags span,.stack span{transition:none}}

/* ---- Motion foundation (phase 2) ---- */
:root{--ease-out:cubic-bezier(.22,1,.36,1);--ease-in-out:cubic-bezier(.65,0,.35,1);--dur-micro:.25s;--dur-ui:.5s;--dur-reveal:1s}
html.lenis,html.lenis body{height:auto}
html.lenis{scroll-behavior:auto}
.lenis.lenis-stopped{overflow:clip}
.lenis.lenis-smooth iframe{pointer-events:none}
.progress{position:fixed;top:0;left:0;right:0;height:3px;z-index:100;background:var(--blue-strong);transform:scaleX(0);transform-origin:0 50%;pointer-events:none}
.rv-mask{display:inline-block;overflow:hidden;vertical-align:top;padding-bottom:.12em;margin-bottom:-.12em}
.rv-word{display:inline-block}
[data-revealing]{transition:none!important}
[tabindex="-1"]:focus{outline:none;box-shadow:none}

/* ---- Nav, intro and hero (phase 3) ---- */
html:not(.lenis){scroll-padding-top:90px} /* native jumps; Lenis gets its offset in main.js */
nav{position:sticky;top:0;z-index:50;transition:transform .5s var(--ease-out)}
nav::before{content:"";position:absolute;inset:0 calc(50% - 50vw);z-index:-1;background:rgba(247,240,232,.85);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);border-bottom:1px solid var(--line);opacity:0;transition:opacity .3s}
html.scrolled nav::before{opacity:1}
html.nav-hidden nav{transform:translateY(-100%)}
.nav-links{position:relative}
nav .nav-links a.is-active{color:var(--ink);background-size:0 1.5px}
.nav-ind{position:absolute;left:0;bottom:-3px;width:1px;height:2px;background:var(--blue-text);transform-origin:0 50%;opacity:0;pointer-events:none}

.logo{display:inline-flex;overflow:hidden;padding:0 .2em .1em 0;margin:0 -.2em -.1em 0}
.logo-word{display:inline-block}
.logo-dot{position:relative;color:transparent}
.logo-dot::after{content:"";position:absolute;left:.04em;bottom:.34em;width:.36em;height:.36em;border-radius:50%;background:var(--blue);box-shadow:inset 0 0 0 1px rgba(31,111,159,.45)}
@keyframes rise{from{transform:translateY(110%)}}
@keyframes pop{0%{transform:scale(0)}60%{transform:scale(1.6)}100%{transform:scale(1)}}
@media(prefers-reduced-motion:no-preference){
  html:not(.intro-seen) .logo-word{animation:rise .7s var(--ease-out) .05s backwards}
  html:not(.intro-seen) .logo-dot::after{animation:pop .5s var(--ease-out) .55s backwards}
}

/* Hero entrance is CSS-only so the H1 (LCP) never waits for JS. "backwards" fill only
   holds the start state during the delay, so JS transforms (magnetic) work afterwards. */
.hero{position:relative;isolation:isolate}
h1 .line{display:block;overflow:hidden;padding-bottom:.14em;margin-bottom:-.14em}
h1 .line>span{display:block;animation:line-up .9s var(--ease-out) backwards}
h1 .line:nth-child(1)>span{animation-delay:.1s}
h1 .line:nth-child(2)>span{animation-delay:.18s}
h1 .line:nth-child(3)>span{animation-delay:.26s}
@keyframes line-up{from{transform:translateY(105%)}}
h1 .mark{position:relative;z-index:0;white-space:nowrap}
h1 .mark::before{content:"";position:absolute;left:-.05em;right:-.05em;bottom:.26em;height:.3em;z-index:-1;border-radius:.05em;background:var(--blue);transform-origin:0 50%;animation:sweep .7s var(--ease-in-out) .95s backwards}
@keyframes sweep{from{transform:scaleX(0)}}
@keyframes slide-in{from{opacity:0;transform:translateX(-16px)}}
.hero .pill{animation:slide-in .7s var(--ease-out) backwards}
@keyframes nudge-up{from{transform:translateY(14px)}}
.hero .lead{animation:nudge-up .9s var(--ease-out) .3s backwards} /* transform only: an opacity fade would delay LCP (the lead is the LCP element) */
.hero .btn{animation:up .8s var(--ease-out) .5s backwards}
.hero .btn.soft{animation-delay:.58s}
.hero .btn.main::after{content:"→";content:"→"/"";display:inline-block;margin-left:8px;transition:transform .3s var(--ease-out)}
.hero .btn.main:hover::after{transform:translateX(4px)}
.hero .btn.is-magnetic{transition:box-shadow .2s,background-color .2s}
/* soft-light keeps the blue clean on the warm background; a plain low-alpha blue turns grey */
.hero-glow{position:absolute;left:0;top:0;width:560px;height:560px;margin:-280px 0 0 -280px;z-index:-1;border-radius:50%;background:radial-gradient(closest-side,rgba(137,207,240,.5),rgba(137,207,240,0));mix-blend-mode:soft-light;opacity:0;transition:opacity .6s;pointer-events:none}
.hero-glow.is-on{opacity:1}

/* Custom cursor: fine pointers with motion allowed only (added by JS). */
html.has-cursor,html.has-cursor *{cursor:none}
.cursor{position:fixed;left:0;top:0;z-index:200;pointer-events:none;mix-blend-mode:difference;opacity:0;transition:opacity .2s}
.cursor.is-visible{opacity:1}
.cursor-dot{position:absolute;left:-6px;top:-6px;width:12px;height:12px;border-radius:50%;background:#fff;transition:transform .45s var(--ease-out),background-color .3s}
.cursor-label{position:absolute;left:0;top:0;transform:translate(-50%,-50%) scale(.6);font-size:13px;font-weight:600;letter-spacing:.02em;color:var(--on-blue);white-space:nowrap;opacity:0;transition:opacity .25s,transform .45s var(--ease-out)}
.cursor[data-state="link"] .cursor-dot{transform:scale(2.6)}
.cursor[data-state="button"] .cursor-dot{transform:scale(.5)}
.cursor[data-state="open"]{mix-blend-mode:normal}
.cursor[data-state="open"] .cursor-dot{transform:scale(6.5);background:var(--blue)}
.cursor[data-state="open"] .cursor-label{opacity:1;transform:translate(-50%,-50%)}
.cursor[data-state="hidden"]{opacity:0}

@media(prefers-reduced-motion:reduce){
  nav,nav::before{transition:none}
  h1 .line>span,h1 .mark::before,.hero .pill,.hero .lead,.hero .btn{animation:none}
  .hero .btn.main::after{transition:none}
}

/* ---- Work showcase (phase 4) ---- */
.section-head{margin-bottom:34px}
.index-label{font:600 13px/1 ui-monospace,Menlo,monospace;letter-spacing:.08em;text-transform:uppercase;color:#6b5548;margin-bottom:16px}
#work .sub{margin-bottom:24px}
.rule{height:1px;background:var(--line);transform-origin:0 50%}
.cards{display:grid;gap:28px}
.card-slot{position:relative;transform-origin:50% 0}
.card-slot::after{content:"";position:absolute;inset:0;border-radius:24px;background:var(--ink);opacity:calc(var(--dim,0)*.1);pointer-events:none}
.card{display:grid;gap:26px}
.card-body{min-width:0}
.card-media{min-width:0;order:-1;display:flex;align-items:center;justify-content:center}
.card-links{display:flex;flex-wrap:wrap;align-items:center;gap:12px 20px}
.card .card-links a{margin:0;white-space:nowrap}
.card .card-links .btn{margin:0}
.card-links a::after{content:"→";content:"→"/"";display:inline-block;margin-left:6px;transition:transform .3s var(--ease-out)}
.card-links a[target="_blank"]::after{content:"↗";content:"↗"/""}
.card-links a[href$=".apk"]::after{content:"↓";content:"↓"/""}
.card-links a:hover::after{transform:translateX(3px)}
.card-links a[target="_blank"]:hover::after{transform:translate(2px,-2px)}
.card-links a[href$=".apk"]:hover::after{transform:translateY(2px)}
.mock{position:relative;width:100%;transition:transform .6s var(--ease-out)}
.glare{position:absolute;inset:0;z-index:2;pointer-events:none;border-radius:inherit;background:radial-gradient(400px circle at var(--gx,50%) var(--gy,50%),rgba(255,255,255,.28),transparent 60%);opacity:0;transition:opacity .4s}
.card:hover .glare{opacity:1}

/* My Cars: browser window; the tall page scrolls inside it on hover/focus */
.browser{max-width:460px;border-radius:12px;overflow:hidden;background:#fff;border:1px solid var(--line);box-shadow:0 24px 50px -28px rgba(58,46,41,.45)}
.browser-bar,.term-bar{display:flex;align-items:center;gap:6px;padding:10px 12px}
.browser-bar{background:var(--bg);border-bottom:1px solid var(--line)}
.browser-bar i,.term-bar i{width:9px;height:9px;border-radius:50%;background:var(--line)}
.browser-bar span{margin-left:10px;flex:1;max-width:240px;padding:3px 10px;border-radius:99px;background:var(--card);font-size:11px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.browser-view{height:290px;overflow:hidden;container-type:size}
.browser-view img{display:block;width:100%;height:auto;transition:transform 1.2s var(--ease-out)}

/* MathWizard: two phones; pixel art is never smooth-scaled. Screen = phone width - 12px:
   160px on phones (1/3 of the 480px art), 240px from 900px (1/2), nearest-neighbour either way. */
.phones{position:relative;width:282px;height:384px}
.phone{position:absolute;top:0;width:172px;padding:6px;border-radius:22px;background:#241c19;box-shadow:0 20px 40px -22px rgba(36,28,25,.6)}
.phone--front{left:0;z-index:1}
.phone--back{left:110px;top:28px;opacity:.9}
.phone img{display:block;width:100%;height:auto;border-radius:16px;image-rendering:pixelated}
.phone .phone-top{position:absolute;inset:6px;width:calc(100% - 12px);transition:opacity .6s var(--ease-out)}
.card:hover .phone .phone-top,.card:focus-within .phone .phone-top{opacity:0}

/* Server: terminal (static text; JS types a copy once, real text stays for AT/no-JS/reduced motion) */
.term{max-width:460px;margin:0;border-radius:12px;overflow:hidden;background:#241c19;color:#efe4da;box-shadow:0 24px 50px -28px rgba(36,28,25,.6)}
.term-bar{border-bottom:1px solid rgba(239,228,218,.1)}
.term-bar i{background:rgba(239,228,218,.22)}
.term-bar span{margin-left:10px;font:11px ui-monospace,Menlo,monospace;color:rgba(239,228,218,.6)}
.term-body{margin:0;padding:14px 16px 6px;font:12px/1.7 ui-monospace,Menlo,monospace;white-space:pre-wrap;word-break:break-word}
.term-prompt{color:var(--blue)}
.term-note{padding:0 16px 12px;font-size:11px;color:rgba(239,228,218,.6)}
.term-live .rest{visibility:hidden}
.term-live .cur{visibility:visible;color:transparent;background:var(--blue);animation:blink 1s steps(1) infinite}
@keyframes blink{50%{opacity:0}}
.sr-only{position:absolute!important;width:1px;height:1px;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

@media(min-width:900px){
  .card{grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);align-items:center;gap:36px;padding:36px}
  .card-media{order:0}
  .phones{width:390px;height:564px}
  .phone{width:252px}
  .phone--back{left:138px;top:36px}
  .browser-view{height:320px}
  .term-body{font-size:13px}
}

/* Stacking cards (JS adds .is-stacking only with motion allowed and a roomy viewport) */
.cards.is-stacking{gap:48px}
.cards.is-stacking .card-slot{position:sticky;top:96px}
.cards.is-stacking .card{min-height:560px}

@media(hover:hover) and (prefers-reduced-motion:no-preference){
  .card:hover .browser-view img,.card:focus-within .browser-view img{transform:translateY(calc(-100% + 100cqh));transition:transform 8s cubic-bezier(.45,0,.55,1)}
  .card:hover .mock:not(.phones){transform:scale(1.02)} /* no zoom on pixel art */
  .card .tags span{transition:transform .35s var(--ease-out),background-color .2s,border-color .2s}
  .card:hover .tags span{transform:translateY(-3px)}
  .card .tags span:nth-child(2){transition-delay:.04s,0s,0s}
  .card .tags span:nth-child(3){transition-delay:.08s,0s,0s}
  .card .tags span:nth-child(4){transition-delay:.12s,0s,0s}
}
@media(prefers-reduced-motion:reduce){
  .card-links a::after,.mock,.browser-view img,.phone .phone-top{transition:none}
}

/* ---- About, contact and footer (phase 5) ---- */
/* Arrival highlight for in-page links that land on a paragraph (native :target, or .is-arrived via JS) */
.fill-w{opacity:.7;transition:opacity .45s var(--ease-out)} /* 70% ink still passes 4.5:1 */
.fill-w.is-lit{opacity:1}
[data-arrive]{border-radius:6px}
[data-arrive]:target,[data-arrive].is-arrived{animation:arrive 2.2s var(--ease-out)}
@keyframes arrive{0%,30%{background-color:var(--blue-soft);box-shadow:0 0 0 10px var(--blue-soft)}100%{background-color:rgba(191,227,247,0);box-shadow:0 0 0 10px rgba(191,227,247,0)}}

.contact-links{display:flex;flex-wrap:wrap;justify-content:center;gap:12px}
.contact .contact-links .btn{margin:0}
.contact .btn.soft{position:relative}
.contact .btn.soft::after{content:"";position:absolute;left:24px;right:24px;bottom:10px;height:1.5px;background:var(--blue-text);transform:scaleX(0);transform-origin:0 50%;transition:transform .35s var(--ease-out)}
.contact .btn.soft:hover::after{transform:scaleX(1)}

footer{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;gap:8px 22px}
.footer-note::before{content:"";display:inline-block;width:7px;height:7px;margin-right:9px;border-radius:50%;background:var(--blue);vertical-align:1px;animation:pulse 2.4s ease-in-out infinite}
.to-top{color:#6b5548;text-decoration:none;background:linear-gradient(var(--blue-text),var(--blue-text)) no-repeat 0 100%/0 1.5px;transition:color .2s,background-size .3s var(--ease-out)}
.to-top:hover{color:var(--ink);background-size:100% 1.5px}
.to-top::after{content:"↑";content:"↑"/"";display:inline-block;margin-left:6px;transition:transform .3s var(--ease-out)}
.to-top:hover::after{transform:translateY(-3px)}

/* "Copied" toast (role=status, filled by JS) */
.toast{position:fixed;left:50%;bottom:24px;z-index:150;display:flex;align-items:center;gap:10px;max-width:calc(100% - 32px);padding:12px 18px;border-radius:14px;background:var(--ink);color:#fff8f2;font-size:14px;font-weight:600;box-shadow:0 18px 40px -18px rgba(58,46,41,.6);transform:translate(-50%,16px);opacity:0;pointer-events:none;transition:opacity .3s,transform .5s var(--ease-out)}
.toast::before{content:"";flex:none;width:8px;height:8px;border-radius:50%;background:var(--blue)}
.toast.is-visible{opacity:1;transform:translate(-50%,0)}

@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto} /* the original smooth scroll-behavior also made native jumps glide */
  .footer-note::before{animation:none}
  .contact .btn.soft::after,.to-top,.to-top::after{transition:none}
  .toast{transition:opacity .15s;transform:translate(-50%,0)}
}

/* ---- Polish and hardening (phase 6) ---- */
/* Contrast nudges, approved by Arlindo 2026-11-12: same hues, darkened just past WCAG AA
   on every background they sit on (values and ratios in docs/audit.md). */
:root{--muted:#726259;--accent:#ab5e3d}
nav a{color:#6b5b54}             /* sits on the warm glow's darkest corner */
h1 .hl{color:#bd6b47}            /* large text: 3:1 is enough, so it stays closer to the original */
.tags span{color:#89654f}
.contact p{color:#755645}
.about-more{margin-top:14px}     /* was an inline style attribute (blocked by a strict CSP) */
