/* FONTS, hosted here instead of fetched from Google Fonts (see docs/DEPLOY.md, section 8). Baloo 2 (headings) and Nunito (text)
   are open source under the SIL Open Font License 1.1. Each is one variable file per script, so one file covers every weight. */
@font-face{font-family:'Baloo 2';font-style:normal;font-weight:700 800;font-display:swap;src:url(../assets/fonts/baloo2-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Baloo 2';font-style:normal;font-weight:700 800;font-display:swap;src:url(../assets/fonts/baloo2-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Nunito';font-style:normal;font-weight:500 800;font-display:swap;src:url(../assets/fonts/nunito-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Nunito';font-style:normal;font-weight:500 800;font-display:swap;src:url(../assets/fonts/nunito-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}

/* ---------- COLOUR PALETTES ----------
   --bg / --bg2   page and card backgrounds
   --primary      nav bar, outlines, secondary accents
   --primary-hi   lighter version of primary, used for small text and icons
   --cta          call-to-action colour (Contact button, buttons, highlights)
   (Graphite & Amber is the chosen colourway.) */
:root{
  color-scheme:dark;
  /* Graphite & Amber (default) */
  --bg:#0d0e11; --bg2:#1b1d24; --primary:#333948; --primary-hi:#aab6cf;
  --cta:#f5a524; --cta-hi:#ffb84a; --cta-dark:#a86d0c; --on-cta:#1a1204;
  --cream:#f4eddf; --text:#f3f3f1; --muted:#aeb2bd; --ink:#1a1d26; --ink2:#5b6070;
  --white:#fff;
  --score:#66cc33; --on-score:#0b1400;   /* Metacritic green and the dark number on it */
  --ok:#7be0a0; --err:#ff9a9a;            /* form status messages */

  --line:color-mix(in srgb,var(--primary-hi) 28%,transparent);
  --card:color-mix(in srgb,var(--bg2) 90%,transparent);
  --head:"Baloo 2","Trebuchet MS",system-ui,sans-serif;
  --body:"Nunito","Segoe UI",system-ui,sans-serif;
}

*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{font-family:var(--body);background:var(--bg);color:var(--text);line-height:1.65;font-size:17px;overflow-x:hidden}
a{color:inherit}
img{max-width:100%;display:block}
h1,h2,h3{font-family:var(--head);line-height:1.1;font-weight:800;text-wrap:balance}
h2,.page-title{font-size:clamp(2rem,4.5vw,3.2rem);text-transform:uppercase;margin-bottom:.5em}
h2 em,.page-title em{font-style:normal;color:var(--cta)}
h3{font-size:1.35rem}

/* nav: capsule with one call-to-action pill */
.sj-header{position:fixed;inset:0 0 auto 0;z-index:50;display:flex;align-items:center;justify-content:space-between;padding:16px 4vw;pointer-events:none}
.sj-header>*{pointer-events:auto}
.sj-header::before{content:"";position:absolute;inset:0 0 -34px 0;z-index:-1;pointer-events:none;background:linear-gradient(color-mix(in srgb,var(--bg) 95%,transparent) 45%,transparent)}

.sj-brand{flex:none;text-decoration:none}
.sj-mark{display:grid;place-items:center;height:60px}
.sj-mark img{height:60px;width:auto;display:block;filter:drop-shadow(0 4px 12px rgba(0,0,0,.5))}
.sj-tagline{font-family:var(--head);font-weight:700;font-size:1.15rem;color:var(--cream);text-shadow:0 2px 12px rgba(0,0,0,.7);white-space:nowrap;flex:1;min-width:0;text-align:center;padding:0 20px;overflow:hidden;text-overflow:ellipsis}
.sj-pill{display:flex;align-items:center;background:var(--primary);border-radius:999px;box-shadow:0 6px 24px rgba(0,0,0,.4)}
.sj-pill a{position:relative;display:block;padding:12px 26px;font-size:1.08rem;font-weight:600;text-decoration:none;border-radius:999px;transition:background .2s}
.sj-pill a:hover{background:rgba(255,255,255,.14)}
.sj-pill a.active{background:color-mix(in srgb,var(--bg) 45%,transparent)}
.sj-pill a.sj-cta{background:var(--cta);color:var(--on-cta);font-weight:800;margin-left:6px;outline:2px solid color-mix(in srgb,var(--primary-hi) 45%,transparent);outline-offset:5px}
.sj-pill a.sj-cta:hover{background:var(--cta-hi)}
.sj-pill a.sj-cta.active{box-shadow:inset 0 0 0 3px var(--bg)}
.sj-dd{position:relative}
.sj-dd>a .sj-caret{display:inline-block;margin-left:8px;border:5px solid transparent;border-top-color:currentColor;border-bottom:0;vertical-align:middle}
.sj-menu{position:absolute;top:100%;left:50%;transform:translateX(-50%);padding-top:12px;display:none;min-width:190px;z-index:5}
.sj-menu::before{content:"";position:absolute;inset:12px 0 0 0;background:var(--primary);border-radius:22px;box-shadow:0 10px 30px rgba(0,0,0,.45);z-index:-1}
.sj-menu a{margin:6px 8px;text-align:center}
.sj-menu a:first-child{margin-top:8px}.sj-menu a:last-child{margin-bottom:8px}
.sj-dd:hover .sj-menu,.sj-dd:focus-within .sj-menu{display:block}
.sj-dd.closed .sj-menu{display:none}   /* Esc closes the dropdown until the link is hovered or focused again */
.sj-badge{position:absolute;top:-8px;right:-4px;min-width:26px;height:26px;border-radius:50%;background:var(--cta);color:var(--on-cta);border:3px solid var(--bg);font-size:.8rem;font-weight:800;display:grid;place-items:center}
.sj-burger{display:none;background:var(--primary);border:0;color:var(--white);font-size:1.6rem;width:48px;height:48px;border-radius:50%;cursor:pointer}

/* hero slideshow */
.hero{position:relative;height:min(100vh,900px);min-height:560px;display:grid;place-items:center;overflow:hidden;isolation:isolate}
/* key art sits behind the name: slightly blurred and dimmed so the text stays readable; scaled up a little so the blur never shows an edge */
.slide{position:absolute;inset:0;z-index:-2;background:center/cover no-repeat;opacity:0;filter:blur(3px);transform:scale(1.06);transition:opacity 1.6s ease,transform 0s 1.6s}
/* the zoom is a transition, not an animation, so a leaving slide keeps its size while it fades and only resets once it is invisible */
.slide.on{opacity:.55;transform:scale(1.14);transition:opacity 1.6s ease,transform 12s ease-out}
.hero::after{content:"";position:absolute;inset:0;z-index:-1;background:linear-gradient(180deg,color-mix(in srgb,var(--bg) 35%,transparent),color-mix(in srgb,var(--bg) 10%,transparent) 40%,color-mix(in srgb,var(--bg) 80%,transparent))}
.hero-text{text-align:center;padding:0 4vw;max-width:1100px}
.hero h1{font-size:clamp(2.2rem,9.2vw,9rem);white-space:nowrap;text-transform:uppercase;text-shadow:0 6px 0 var(--bg2),0 12px 40px rgba(0,0,0,.55)}
.hero .role{font-family:var(--head);font-weight:800;font-size:clamp(1.3rem,3.4vw,2.4rem);color:var(--cta);text-shadow:0 2px 2px rgba(0,0,0,.9),0 4px 12px rgba(0,0,0,.85),0 0 32px rgba(0,0,0,.7);margin-top:6px}
.hero .bio{max-width:none;margin:18px auto 0;font-size:clamp(1rem,1.7vw,1.25rem);color:var(--cream);font-weight:600;text-shadow:0 1px 2px rgba(0,0,0,.95),0 2px 10px rgba(0,0,0,.9),0 0 28px rgba(0,0,0,.75)}
/* the name, title and bio fade in and rise from below, one after another. hero.js adds .hero-skip on the first scroll, which jumps them to the end. */
@keyframes hero-in{from{opacity:0;transform:translateY(48px)}to{opacity:1;transform:none}}
.js .hero h1,.js .hero .role,.js .hero .bio{animation:hero-in 1s cubic-bezier(.2,.7,.2,1) backwards}
.js .hero .role{animation-delay:.25s}
.js .hero .bio{animation-delay:.5s}
.js .hero .social-icons.reveal{opacity:1;transform:none;transition:none;animation:hero-in 1s cubic-bezier(.2,.7,.2,1) .75s backwards}
.js .hero.hero-skip h1,.js .hero.hero-skip .role,.js .hero.hero-skip .bio{animation:none}
.dots{position:absolute;bottom:28px;left:50%;transform:translateX(-50%);display:flex;gap:10px}
.dots button{width:12px;height:12px;border-radius:50%;border:2px solid var(--white);background:transparent;cursor:pointer;padding:0}
.dots button.on{background:var(--cta);border-color:var(--cta)}
.cue{position:absolute;bottom:64px;left:50%;transform:translateX(-50%);font-weight:700;color:var(--cream);text-decoration:none;opacity:.85}

/* sections with blurred game-image backgrounds */
.panel{position:relative;padding:64px 5vw 56px;isolation:isolate;overflow:hidden;overflow:clip}
.panel.top{padding-top:150px;min-height:min(100vh,900px)}
/* section backgrounds: the pictures Samuel supplies in assets/bg/, and how much each is blurred. A section picks one with a class
   such as bg-cv. (url() here is read relative to this stylesheet, hence ../assets.) */
.bg-employment{--bg-img:url(../assets/bg/employment.jpg);--blur:10px}
.bg-commercial{--bg-img:url(../assets/bg/commercial.jpg);--blur:10px}
#commercial.bg-commercial{--blur:8px}
.bg-tools{--bg-img:url(../assets/bg/tools.jpg);--blur:10px}
.bg-portfolio{--bg-img:url(../assets/bg/portfolio.jpg);--blur:10px}
.bg-personal{--bg-img:url(../assets/bg/personal.jpg);--blur:10px}
.bg-cv{--bg-img:url(../assets/bg/cv.jpg);--blur:12px}
.bg-blog{--bg-img:url(../assets/bg/blog.jpg);--blur:10px}
.bg-contact{--bg-img:url(../assets/bg/contact.jpg);--blur:12px}
.panel::before{content:"";position:absolute;inset:-40px;z-index:-2;background:var(--bg-img,none) center/cover no-repeat,linear-gradient(135deg,var(--bg2),var(--bg));filter:blur(var(--blur,8px)) brightness(.5) saturate(1.1)}
.panel::after{content:"";position:absolute;inset:0;z-index:-1;background:linear-gradient(180deg,color-mix(in srgb,var(--bg) 50%,transparent),color-mix(in srgb,var(--bg) 25%,transparent) 50%,color-mix(in srgb,var(--bg) 40%,transparent))}
.skip-link{position:absolute;left:12px;top:-60px;z-index:200;padding:10px 18px;border-radius:999px;background:var(--cta);color:var(--on-cta);font-weight:800;text-decoration:none}
.skip-link:focus{top:12px}
.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.noscript{position:relative;z-index:5;padding:96px 5vw 20px;background:var(--bg2);color:var(--cream)}
.noscript a{color:var(--cta)}
.wrap{width:min(1150px,100%);margin:auto}
.wrap.narrow{width:min(900px,100%)}
.center{text-align:center}
.gap-top{margin-top:56px}
.note-top{margin-top:22px}
.intro{max-width:620px;color:var(--cream);font-size:1.15rem;margin-bottom:28px}
.btn{display:inline-block;padding:13px 30px;border-radius:999px;background:var(--cta);color:var(--on-cta);font-weight:800;text-decoration:none;border:0;cursor:pointer;font:inherit;font-weight:800;box-shadow:0 5px 0 var(--cta-dark);transition:.15s}
.btn:hover{transform:translateY(-3px);box-shadow:0 8px 0 var(--cta-dark)}
.more{margin-top:24px}
.panel h2,.panel .page-title{margin-bottom:.35em}

/* cards */
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(290px,1fr));gap:22px}
.card{background:var(--card);border:2px solid var(--line);border-radius:22px;padding:26px;min-width:0}
a.card{text-decoration:none;display:block;transition:.2s}
a.card:hover{transform:translateY(-6px);border-color:var(--cta)}
.card h3{margin-bottom:4px}
.meta{color:var(--cta);font-weight:700;font-size:.95rem}
.card p,.card li{color:var(--muted)}
.card ul{padding-left:20px;margin-top:10px;display:grid;gap:6px}
.thumb{height:180px;margin:-26px -26px 20px;border-radius:20px 20px 0 0;background:var(--img,none) center/cover,linear-gradient(135deg,var(--primary),var(--bg2))}
/* chips: .chip is a small label (a technology, a link); .chip-btn adds what a button needs */
.chip{display:inline-block;margin:12px 6px 0 0;padding:2px 12px;border-radius:999px;background:color-mix(in srgb,var(--cta) 16%,transparent);color:var(--cta);font-size:.82rem;font-weight:700;text-decoration:none}
.chip-btn{border:0;cursor:pointer;font:inherit;font-weight:700}
/* About me + How I work: two columns split by a divider; stacked on narrow screens */
.about-split{display:grid;grid-template-columns:minmax(0,1fr) 3px minmax(0,1.1fr);gap:clamp(24px,4vw,56px);align-items:stretch}
.about-col h2{margin-bottom:.4em}
.about-col>p{color:var(--cream);font-size:1rem;line-height:1.5;margin-bottom:.8em;max-width:560px}
.about-divider{border-radius:3px;background:linear-gradient(180deg,transparent,var(--cta) 12%,var(--cta) 88%,transparent);opacity:.85}
.how-stack{display:grid;gap:10px}
.how-stack .card{padding:14px 20px;border-radius:16px}
.how-stack .card h3{font-size:1.05rem;margin-bottom:2px}
.how-stack .card p{font-size:.95rem;line-height:1.4;margin:0}
@media (max-width:820px){
  .about-split{grid-template-columns:1fr;gap:28px}
  .about-divider{width:100%;height:3px;background:linear-gradient(90deg,transparent,var(--cta) 12%,var(--cta) 88%,transparent)}
}

/* tag filter (Personal page): a row of chip buttons above the timeline */
.filters{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 6px}
.filters .chip{margin:0;padding:8px 16px;font-size:.9rem}
.filters .chip[aria-pressed="true"]{background:var(--cta);color:var(--on-cta)}
.filter-count{color:var(--muted);font-size:.9rem;margin:0 0 26px}
.tl-item[hidden],.tl-group[hidden]{display:none}

/* employment timeline */
.timeline{border-left:4px solid var(--cta);padding-left:26px;display:grid;gap:22px}
.timeline .card{position:relative}
.timeline .card::before{content:"";position:absolute;left:-42px;top:32px;width:18px;height:18px;border-radius:50%;background:var(--cta);border:4px solid var(--bg)}

/* project timeline: Commercial and Personal pages, same rail and dots as the home timeline */
.tl{border-left:4px solid var(--cta);padding-left:26px}
.tl-item{position:relative}
.tl-item::before{content:"";position:absolute;left:-42px;top:32px;width:18px;height:18px;border-radius:50%;background:var(--cta);border:4px solid var(--bg)}
.tl-year{position:sticky;top:84px;z-index:6;width:max-content;margin:0 0 14px -33px}
.tl-year span{display:inline-block;padding:3px 18px;border-radius:999px;background:var(--cta);color:var(--on-cta);font-family:var(--head);font-weight:800;font-size:1.2rem;line-height:1.5;box-shadow:0 4px 14px rgba(0,0,0,.5)}
/* skills */
.group{margin-top:34px}
.group h3{color:var(--primary-hi);font-size:1.1rem;letter-spacing:.14em;text-transform:uppercase;margin-bottom:14px}
.skills{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:16px}
.skill{display:grid;grid-template-columns:56px 1fr;gap:16px;align-items:start;padding:18px}
.skill .ico{width:56px;height:56px;border-radius:16px;background:rgba(244,247,255,.08);display:grid;place-items:center}
.skill .ico img{width:30px;height:30px;filter:brightness(0) invert(1)}
.skill .ico b{font-family:var(--head);font-size:1.15rem;color:var(--cream)}
.skill h4{font-family:var(--head);font-size:1.15rem;line-height:1.2;display:flex;flex-wrap:wrap;gap:4px 10px;align-items:center}
.lvl{font-family:var(--body);font-size:.75rem;font-weight:800;padding:1px 10px;border-radius:999px;background:color-mix(in srgb,var(--primary-hi) 22%,transparent);color:var(--primary-hi)}
.lvl.pro{background:color-mix(in srgb,var(--cta) 22%,transparent);color:var(--cta)}
.skill .yrs{color:var(--cream);font-weight:700;font-size:.95rem}
.skill p{font-size:.95rem}

/* portfolio entries */
/* project cards: the Featured slide (.fslide) and the Commercial / Personal entry (.entry) share one layout, a picture box (at least square, stretched to the card height) then the text */
.fslide,.entry{display:grid;gap:0;padding:0;overflow:hidden;min-width:0}
.entry{grid-template-columns:minmax(0,5fr) minmax(0,7fr);margin-bottom:24px}
/* width:100% keeps the box inside its column: with only aspect-ratio and stretch, a card whose text is taller than the column is
   wide made the box wider too (to stay square), and it covered the start of the text. Now it is square at least, and taller when
   the text is */
.fmedia,.entry .media{position:relative;width:100%;aspect-ratio:1/1;align-self:stretch}
.fbody,.entry .body{padding:26px}
.entry h3{font-size:1.7rem}
.card p.roleline{color:var(--cream);font-weight:700;margin:2px 0 6px}
.card ul.roles{margin:0 0 8px;padding-left:20px;color:var(--cream);font-weight:700;gap:2px}
.projlist a{color:var(--cream);text-decoration:none;border-bottom:1px solid var(--line)}
.projmeta{display:block;color:var(--muted);font-size:.92rem;margin-top:2px}
.projlist a:hover{color:var(--cta);border-color:var(--cta)}
.timeline .projlist+.m-toggle+.m-more{margin-top:12px;padding-top:4px;border-top:1px solid var(--line)}

/* CV paper */
.paper{background:var(--cream);color:var(--ink);border-radius:18px;padding:clamp(24px,5vw,56px);box-shadow:0 20px 60px rgba(0,0,0,.45)}
.paper h1{font-size:clamp(2.2rem,5vw,3.4rem);text-transform:uppercase;color:var(--ink)}
.paper .sub{font-weight:800;color:var(--ink2);margin:4px 0 2px}
.paper .loc{color:var(--ink2)}
.paper h2{font-size:1.4rem;color:var(--ink);border-bottom:3px solid var(--cta-dark);padding-bottom:4px;margin:34px 0 14px;display:block}
.paper h3{font-size:1.2rem;color:var(--ink);margin-top:20px}
.paper .when{font-style:italic;color:var(--ink2);margin-bottom:6px}
.paper ul{padding-left:22px;display:grid;gap:7px;margin:8px 0}
.paper p{margin-bottom:10px}
.paper li::marker{color:var(--cta-dark)}
.paper .small{font-size:.95rem;color:var(--ink2)}

/* featured projects carousel */
.feature{position:relative;max-width:1240px;margin:36px auto 0;overflow-x:clip}
.fwrap{position:relative}
/* the Commercial and Personal cards are as wide as the front carousel card, so they line up (keep in step with .fslide) */
.fmatch{width:min(1000px,86%);margin-inline:auto;grid-template-columns:repeat(auto-fit,minmax(min(290px,100%),1fr))}
/* all slides share one grid cell, so the box is always as tall as the tallest slide */
.fstage{display:grid}
/* a coverflow: the front card is full size, the cards before and after peek out at the sides, smaller and dimmed */
.fslide{grid-area:1/1;justify-self:center;width:min(1000px,86%);grid-template-columns:minmax(0,5fr) minmax(0,6fr);visibility:hidden;opacity:0;transform:scale(.7);transition:transform .5s ease,opacity .5s ease,visibility .5s,filter .5s}
.fslide.on{visibility:visible;opacity:1;transform:none;z-index:2}
.fslide.before,.fslide.after{visibility:visible;opacity:.5;filter:brightness(.7);z-index:1;cursor:pointer}
.fslide.before{transform:translateX(-92%) scale(.82)}
.fslide.after{transform:translateX(92%) scale(.82)}
.fslide.no-media,.entry.no-media{grid-template-columns:minmax(0,1fr)}
.fbody{display:flex;flex-direction:column;gap:6px;min-height:0}
.fbody h3{font-size:clamp(1.4rem,2.6vw,1.9rem)}
.fbody h4{margin-top:8px;font-family:var(--head);color:var(--cream)}
.acts{display:flex;flex-wrap:wrap;gap:10px;margin-top:18px}
.fbody .acts{margin-top:auto;padding-top:12px}
/* Metacritic score: logo and a big number */
.mc{position:absolute;left:16px;bottom:16px;display:flex;align-items:center;gap:12px;padding:8px 16px 8px 12px;border-radius:18px;background:color-mix(in srgb,var(--bg) 82%,transparent);backdrop-filter:blur(8px);box-shadow:0 6px 20px rgba(0,0,0,.45);z-index:2}
.mc img{width:34px;height:34px;filter:brightness(0) invert(1);flex:none}
.mc b{font-family:var(--head);font-weight:800;font-size:2.6rem;line-height:1;color:var(--on-score);background:var(--score);border-radius:12px;min-width:68px;height:60px;display:grid;place-items:center;padding:0 10px}
.mc small{font-weight:800;font-size:.8rem;color:var(--cream);letter-spacing:.06em}
.btn.sm{padding:9px 22px;font-size:.95rem;box-shadow:0 4px 0 var(--cta-dark)}
.btn.alt{background:transparent;color:var(--text);border:2px solid var(--primary-hi);box-shadow:none}
.btn.alt:hover{background:var(--primary);box-shadow:none}
/* the arrows sit on the edges of the front card, level with its middle */
.fnav{position:absolute;inset:0;pointer-events:none;z-index:3}
.fnav button{position:absolute;top:calc(50% - 22px);width:44px;height:44px;padding:0;display:grid;place-items:center;border-radius:50%;border:1px solid color-mix(in srgb,var(--cream) 30%,transparent);background:color-mix(in srgb,var(--bg) 78%,transparent);backdrop-filter:blur(8px);color:var(--cream);cursor:pointer;pointer-events:auto;box-shadow:0 6px 18px rgba(0,0,0,.5);transition:background .15s,color .15s,border-color .15s}
.fnav button svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round}
.fnav button:hover,.fnav button:focus-visible{background:var(--cta);border-color:var(--cta);color:var(--on-cta)}
.fnav .prev{left:calc(50% - min(500px,43%) - 60px)}
.fnav .next{right:calc(50% - min(500px,43%) - 60px)}
.ftimer{position:absolute;bottom:4px;right:calc(50% - min(500px,43%));width:24px;height:24px;transform:rotate(-90deg);opacity:0;transition:opacity .3s}
.ftimer circle{fill:none;stroke-width:3}
.ftimer .bg{stroke:var(--line)}
.ftimer .arc{stroke:var(--cta);stroke-dasharray:1;stroke-dashoffset:1;stroke-linecap:round}
@keyframes ftimer{to{stroke-dashoffset:0}}
.fdots{display:flex;justify-content:center;gap:10px;margin-top:20px}
.fdots button{width:12px;height:12px;border-radius:50%;border:2px solid var(--primary-hi);background:transparent;padding:0}
.fdots button.on{background:var(--cta);border-color:var(--cta)}
/* logo-only buttons (Steam, YouTube, the project page): the name shows on hover or focus */
.btn.ico{position:relative;display:grid;place-items:center;width:46px;height:46px;padding:0}
.btn.ico img{width:22px;height:22px;filter:brightness(0) opacity(.85)}
.btn.ico.alt img{filter:brightness(0) invert(1)}
.btn.ico::after{content:attr(data-label);position:absolute;left:50%;bottom:calc(100% + 10px);z-index:3;transform:translate(-50%,4px);white-space:nowrap;padding:4px 10px;border-radius:8px;background:var(--bg2);border:1px solid var(--line);color:var(--cream);font-size:.82rem;font-weight:700;opacity:0;pointer-events:none;transition:opacity .15s,transform .15s}
.btn.ico:hover::after,.btn.ico:focus-visible::after{opacity:1;transform:translate(-50%,0)}
.btn.ico.view-project{width:auto;padding:9px 22px;display:inline-block}
.btn.ico.view-project img,.btn.ico.view-project::after{display:none}
/* a card title never runs past two lines */
.fbody h3,.entry h3,a.card h3{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
/* a card's title is a link to the project's own page */
.title-link{text-decoration:none}
.title-link:hover{color:var(--cta)}
/* expandable sections on each project: Details, Key contributions / Technical details */
/* tabs on the Commercial / Personal cards: a strip that scrolls sideways when it is too wide, over a fixed-height box whose text scrolls */
.tabs{margin-top:12px}
.tablist{display:flex;gap:6px;overflow-x:auto;scrollbar-width:none;border-bottom:2px solid var(--line);margin-bottom:12px}
.tablist::-webkit-scrollbar{display:none}
.tablist button{flex:none;padding:8px 14px;border:0;border-bottom:3px solid transparent;margin-bottom:-2px;background:none;color:var(--muted);font:800 .95rem var(--head);cursor:pointer;white-space:nowrap}
.tablist button:hover{color:var(--cream)}
.tablist button[aria-selected="true"]{color:var(--cream);border-bottom-color:var(--cta)}
.tablist button:focus-visible{outline:2px solid var(--cta);outline-offset:-2px;border-radius:8px}
.tabpanel{height:230px;overflow-y:auto;padding-right:8px;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--primary-hi) transparent}
.tabpanel p+p,.tabpanel ul,.tabpanel ul.roles+p{margin-top:8px}
.tabpanel .more{font-size:.92rem}
.tabpanel .more a{color:var(--cta)}
.tabpanel:focus-visible{outline:2px solid var(--cta);outline-offset:2px;border-radius:8px}

/* blog video player */
.yt{position:relative;aspect-ratio:16/9;width:100%;border-radius:16px;overflow:hidden;margin:16px 0 8px;cursor:pointer;background:linear-gradient(135deg,var(--primary),var(--bg2))}
.yt img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.yt iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.yt-play{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:84px;height:84px;border-radius:50%;background:var(--cta);color:var(--on-cta);display:grid;place-items:center;font-size:2rem;padding-left:6px;box-shadow:0 8px 30px rgba(0,0,0,.5);transition:.2s}
.yt:hover .yt-play{transform:translate(-50%,-50%) scale(1.1)}
.yt-link{display:inline-block;font-size:.9rem;font-weight:700;color:var(--primary-hi);margin-bottom:6px}

/* contact page */
.btn:focus-visible,a:focus-visible,button:focus-visible{outline:3px solid var(--cta);outline-offset:3px}
/* the address is the one big thing on the page; the reasons to write are plain ruled columns, not cards */
.contact{--gap:clamp(30px,5vw,52px);display:grid;gap:var(--gap)}
/* the email sits close under the sentence above it, and the social links close under the email buttons: half the space
   between the page's other blocks (Samuel asked for these two gaps to be halved on 10 Nov 2026) */
.contact .email-card{margin-top:calc(var(--gap) / -2)}
.contact .email-card+.social{margin-top:calc(21px - var(--gap) / 2)}
.contact .intro{max-width:none;margin-bottom:0}
.email-card{display:grid;gap:16px;justify-items:start}
.email-address{font-family:var(--head);font-weight:800;line-height:1.15;font-size:clamp(1rem,4.7vw,1.7rem);color:var(--cream);overflow-wrap:anywhere;text-decoration:underline;text-decoration-color:var(--cta);text-decoration-thickness:.08em;text-underline-offset:.18em}
a.email-address:hover{color:var(--cta)}
.email-actions{display:flex;flex-wrap:wrap;align-items:center;gap:12px}
.btn[hidden]{display:none}
.reasons{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:0 clamp(24px,4vw,56px)}
.reasons>div{border-top:2px solid var(--line);padding-top:16px}
.reasons h3{font-size:1.2rem;color:var(--cream);margin-bottom:8px}
.reasons p{color:var(--muted);font-size:.98rem}
.reasons a{color:var(--text)}
/* social links: a small logo (the SVGs are black, so they are inverted to white) and the name */
.social{list-style:none;display:flex;flex-wrap:wrap;gap:12px 28px}
.social a{display:inline-flex;align-items:center;gap:10px;color:var(--text);text-decoration:none;font-weight:700}
.social a:hover{color:var(--cta)}
.social img{width:22px;height:22px;flex:none;filter:invert(1);transition:opacity .2s}
.social a:hover img{opacity:.7}
/* icon-only social buttons: small and round, white on the dark hero, dark on the CV paper */
.social-icons{list-style:none;display:flex;gap:10px;margin-top:14px}
/* the bio is two sentences, each on one line; the text scales with the screen so neither wraps */
.bio-line{display:block;white-space:nowrap}
@media(max-width:700px){.hero .bio{font-size:3.4vw}}
.hero-cta{margin-top:22px}
.js .hero .hero-cta{animation:hero-in 1s cubic-bezier(.2,.7,.2,1) .65s backwards}
.h-link{color:inherit;text-decoration:none}
.h-link:hover{color:var(--cta)}
.hero .social-icons{justify-content:center;margin-top:20px}
.social-icons a{display:grid;place-items:center;width:36px;height:36px;border-radius:50%;border:2px solid color-mix(in srgb,var(--primary-hi) 45%,transparent);background:color-mix(in srgb,var(--bg) 45%,transparent);transition:background .2s,border-color .2s}
.social-icons a:hover{background:var(--cta);border-color:var(--cta)}
.social-icons img{width:18px;height:18px;filter:invert(1)}
.social-icons a:hover img{filter:none}
.paper .social-icons{display:flex;gap:10px;padding-left:0;margin:10px 0 0}
.paper .social-icons a{border-color:var(--ink2);background:none}
.paper .social-icons a:hover{background:var(--cta);border-color:var(--cta-dark)}
.paper .social-icons img{filter:none}
.stack{display:grid;gap:18px}
.status{min-height:1.5em;font-weight:700}
.status.ok{color:var(--ok)}.status.err{color:var(--err)}
.two{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.1fr);gap:40px;align-items:start}
footer{background:var(--bg);border-top:3px solid var(--cta);padding:30px 5vw;text-align:center;color:var(--muted);font-size:.9rem}


.js .reveal{opacity:0;transform:translateY(24px);transition:.9s cubic-bezier(.2,.7,.2,1)}
.js .reveal.in{opacity:1;transform:none}
/* BREAKPOINTS used below. 900px: the menu collapses into a button and two-column layouts stack. 700px: phones, where long content
   collapses behind buttons, grids get compact and badges shrink. (hover:none): touch screens. CSS variables cannot be used inside
   media queries, so the numbers are written out: change all of them or none. */
@media(prefers-reduced-motion:reduce){.js .hero h1,.js .hero .role,.js .hero .bio,.js .hero .social-icons.reveal{animation:none}.js .reveal{opacity:1;transform:none;transition:none}html{scroll-behavior:auto}.slide.on{transform:scale(1.06);transition:opacity 1.6s ease}}
@media(max-width:900px){
  .sj-burger{display:block}
  .sj-pill{position:absolute;top:70px;right:4vw;flex-direction:column;align-items:stretch;border-radius:24px;padding:8px;display:none;min-width:220px}
  .sj-pill.open{display:flex}
  .sj-pill a.sj-cta{margin:6px 0 0;outline-offset:3px}
  .two,.entry,.fslide,.reasons{grid-template-columns:minmax(0,1fr)}
  .reasons>div{margin-bottom:22px}
  .sj-menu{position:static;transform:none;display:block;padding:0}
  .sj-menu::before{display:none}
  .sj-menu a{margin:2px 0 2px 16px;text-align:left;font-size:.98rem;opacity:.9}
  .sj-dd>a .sj-caret{display:none}
  .sj-tagline{display:none}
}
/* ---------- photo slideshow in the square image box ---------- */
.gal{position:absolute;inset:0;overflow:hidden;background:linear-gradient(135deg,var(--primary),var(--bg2))}
.gslide{position:absolute;inset:0;background:center/cover no-repeat;opacity:0;transition:opacity 1.2s ease}
.gslide.on{opacity:1}
.gal-open{position:absolute;inset:0;border:0;background:none;cursor:zoom-in;z-index:1}
.gal-open[hidden]{display:none}
.gal-chip{position:absolute;right:14px;bottom:14px;padding:6px 14px;border-radius:999px;background:color-mix(in srgb,var(--bg) 82%,transparent);color:var(--cream);font-weight:700;font-size:.85rem;box-shadow:0 4px 14px rgba(0,0,0,.4)}
.gal-open:hover .gal-chip,.gal-open:focus-visible .gal-chip{background:var(--cta);color:var(--on-cta)}
.has-gal .mc{pointer-events:none}
/* full-screen photo view */
.lb{position:fixed;inset:0;z-index:100;background:rgba(5,6,8,.94);display:grid;grid-template-columns:64px minmax(0,1fr) 64px;grid-template-rows:1fr auto;align-items:center}
.lb[hidden]{display:none}
.lb-stage{grid-column:2;grid-row:1;height:100%;display:grid;place-items:center;min-height:0;padding:56px 0 8px;touch-action:pan-y}
.lb-img{max-width:100%;max-height:100%;object-fit:contain;border-radius:10px;box-shadow:0 10px 50px rgba(0,0,0,.6)}
.lb-nav,.lb-close{width:48px;height:48px;border-radius:50%;border:0;background:var(--primary);color:var(--white);font-size:1.8rem;line-height:1;cursor:pointer;display:grid;place-items:center;padding-bottom:4px}
.lb-nav[hidden]{display:none}
.lb-prev{grid-column:1;grid-row:1;justify-self:center}
.lb-next{grid-column:3;grid-row:1;justify-self:center}
.lb-close{position:absolute;top:12px;right:14px;z-index:2}
.lb-nav:hover,.lb-close:hover{background:var(--cta);color:var(--on-cta)}
.lb-bar{grid-column:1/-1;grid-row:2;display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;padding:10px 20px 18px;color:var(--cream)}
.lb-count{color:var(--muted);margin-left:8px}
.lb-yt[hidden]{display:none}

/* ---------- collapsible content, swipe and phone layout ---------- */
.fstage{grid-template-columns:minmax(0,1fr);touch-action:pan-y}
.hero{touch-action:pan-y}
.fdots button{position:relative}
.fdots button::after,.dots button::after{content:"";position:absolute;inset:-12px}
.dots button{position:relative}
.swipe-hint{display:none}
/* "Read more" cards */
.card .full{display:none;white-space:pre-line;color:var(--cream);margin-top:12px}
.card.open .full{display:block}
.m-toggle{display:none}
/* blog: toolbar, then a grid of picture cards. Read more opens a card across the whole row. */
.post-tools{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:14px 24px;margin:6px 0 22px}
.post-search{display:flex;align-items:center;gap:10px;width:min(100%,340px);padding:0 18px;height:46px;border-radius:999px;background:var(--cream);color:var(--ink);box-shadow:0 5px 0 color-mix(in srgb,var(--bg) 55%,transparent)}
.post-search input{flex:1;min-width:0;border:0;outline:0;background:none;font:inherit;font-size:1rem;color:var(--ink)}
.post-search input::placeholder{color:var(--ink2)}
.post-search:focus-within{outline:3px solid var(--cta);outline-offset:3px}
.post-sort{display:flex;align-items:center;gap:14px;color:var(--cream);font-size:1.1rem}
.seg{display:flex;border-radius:999px;background:var(--cream);box-shadow:0 5px 0 color-mix(in srgb,var(--bg) 55%,transparent);overflow:hidden}
.seg button{border:0;cursor:pointer;font:inherit;font-size:1.05rem;padding:0 22px;height:46px;background:none;color:var(--ink)}
.seg button[aria-pressed="true"]{background:var(--cta);color:var(--on-cta);font-weight:800}
.post-flip{width:52px;height:46px;border:0;border-radius:999px;cursor:pointer;display:grid;place-items:center;background:var(--cta);color:var(--on-cta);box-shadow:0 5px 0 var(--cta-dark)}
.post-flip svg{transition:transform .2s}
.post-flip.up svg{transform:rotate(180deg)}
.seg button:focus-visible,.post-flip:focus-visible{outline:3px solid var(--white);outline-offset:3px}
.post-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:34px 28px;align-items:start}
.post-empty{grid-column:1/-1;color:var(--cream);font-size:1.1rem}
.post{display:flex;flex-direction:column;min-width:0;text-decoration:none;color:inherit}
.post-pic{aspect-ratio:16/9;border-radius:26px;background:var(--img,none) center/cover,linear-gradient(135deg,var(--primary),var(--bg2));box-shadow:0 8px 0 color-mix(in srgb,var(--bg) 60%,transparent);margin-bottom:20px}
.post h3{font-size:1.3rem;text-transform:uppercase;letter-spacing:.02em;font-weight:700;color:var(--cream);line-height:1.3;margin-bottom:10px}
.post .meta{color:var(--muted);text-transform:uppercase;letter-spacing:.06em;font-weight:600;font-size:.9rem;margin-top:auto}
.post-more{align-self:flex-start;margin-top:14px;font-weight:700;color:var(--cta)}
.post-more::after{content:"\203A";margin-left:12px;font-size:1.3em;line-height:1}
.post:hover .post-more,.post:focus-visible .post-more{color:var(--cta-hi)}
.post:hover .post-pic{box-shadow:0 8px 0 var(--cta-dark)}
.post:focus-visible{outline:3px solid var(--white);outline-offset:6px;border-radius:26px}
/* one blog post (post.html): reading column, then the latest posts */
.post-page{max-width:760px}
.post-back{display:inline-block;margin-bottom:18px;color:var(--cta);font-weight:700;text-decoration:none}
.post-back:hover{color:var(--cta-hi)}
.post-page .meta{color:var(--muted);text-transform:uppercase;letter-spacing:.06em;font-weight:600;font-size:.95rem}
.post-page .page-title{margin:6px 0 14px}
.post-lede{font-size:1.25rem;color:var(--cream);margin-bottom:6px}
.post-page .yt{margin:22px 0 8px}
.post-body{margin-top:18px}
.post-body p{color:var(--cream);margin-bottom:1.1em}
.post-page .chip{margin:6px 0 0}
.post-latest{margin-top:72px}
/* "Latest news" waits for post.js to fill the post above it, so it does not show and then jump down the page */
.js .post-page:empty~.post-latest{display:none}
.post-latest h2{margin-bottom:.6em}
/* one project (project-<id>.html, built by tools/build.mjs): heading, the gallery, then Overview, my part and the technical details */
.pp{max-width:1000px;margin:auto}
/* the heading: the title with the Metacritic badge beside it, then everything else full width */
.pp-head{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:start;column-gap:20px;margin-bottom:24px}
.pp-head>*{grid-column:1/-1}
.pp-head .page-title{grid-column:1;margin:0 0 12px}
.pp-head .mc{grid-column:2;grid-row:1;position:static}
.pp-head .roleline{color:var(--cream);font-weight:700}
.pp-head ul.roles{padding-left:20px;color:var(--cream);font-weight:700;margin-top:2px}
.pp-head .acts{margin-top:16px}
/* under the title, always one line: the year, the engine logo, then a logo per platform family. Each logo shows its names in a
   label on hover, tap or focus; the last two open their label to the left so it stays on screen */
.pp-sub{list-style:none;display:flex;flex-wrap:nowrap;align-items:center;gap:8px;margin-bottom:12px;min-width:0}
.pp-year{font-family:var(--head);font-weight:800;font-size:1.2rem;color:var(--cta);line-height:1;margin-right:2px}
.pp-sep{flex:none;width:2px;height:22px;margin:0 4px;border-radius:2px;background:var(--line)}
.plat{position:relative;flex:none;display:grid;place-items:center;width:38px;height:38px;border-radius:12px;background:color-mix(in srgb,var(--primary) 70%,transparent);border:1px solid var(--line);cursor:default;transition:background .15s}
.plat img{width:20px;height:20px;filter:brightness(0) invert(1)}
.plat.tech img{width:22px;height:22px}
/* the engine: its logo and a short name (UE5, nTT) */
.plat.tech{width:auto;display:flex;gap:7px;padding:0 12px 0 9px}
.plat.tech span{font-family:var(--head);font-weight:800;font-size:.98rem;color:var(--cream);line-height:1;padding-top:2px}
.plat:hover,.plat:focus{background:var(--primary);outline:none}
.plat:focus-visible{outline:3px solid var(--cta);outline-offset:3px}
.plat::after{content:attr(data-label);position:absolute;left:0;bottom:calc(100% + 8px);z-index:3;white-space:nowrap;padding:4px 10px;border-radius:8px;background:var(--bg2);border:1px solid var(--line);color:var(--cream);font-size:.82rem;font-weight:700;opacity:0;transform:translateY(4px);pointer-events:none;transition:opacity .15s,transform .15s}
.plat:nth-last-child(-n+3)::after{left:auto;right:0}
.plat:hover::after,.plat:focus::after{opacity:1;transform:none}
/* on a card the line sits straight under the title */
.card ul.pp-sub{display:flex;padding-left:0;gap:6px;margin:2px 0 10px;width:100%}
/* on a card the platform logos shrink to fit the line, so it never spills out of a narrow card */
.card .plat:not(.tech){flex:0 1 38px;min-width:22px;width:auto}
.card .plat img{flex:none}
/* a narrow card (three across on a small laptop): drop the separators and the engine's short name; the label still shows on hover */
a.card{container-type:inline-size}
@container (max-width:310px){.pp-sep{display:none}.plat.tech span{display:none}.plat.tech{padding:0 8px}}
.card .pp-sub li{color:inherit}
.card .pp-year{color:var(--cta)}
.plat-text{flex:none;color:var(--muted);font-weight:700;font-size:.95rem;white-space:nowrap}
.pp-head .roleline{color:var(--cream);font-weight:700}
.pp-head ul.roles{padding-left:20px;color:var(--cream);font-weight:700;margin-top:2px}
.pp-head .acts{margin-top:16px}
.pp-head .mc{position:static;flex:none;margin-top:8px}
/* the gallery: one item at a time (project.js). Without JavaScript every item shows, one under another, and the strip is hidden */
.pg{margin-bottom:24px}
.pg-stage{position:relative;display:grid;gap:14px;touch-action:pan-y}
.pg-item{position:relative;aspect-ratio:16/9;border-radius:22px;overflow:hidden;border:2px solid var(--line);background:linear-gradient(135deg,var(--primary),var(--bg2))}
.js .pg-item:not(.on){display:none}
.pg-item .yt{margin:0;border-radius:0;aspect-ratio:auto;height:100%}
.pg-zoom{display:block;width:100%;height:100%;padding:0;border:0;background:none;cursor:zoom-in}
.pg-zoom img{width:100%;height:100%;object-fit:contain}
.pg-nav{display:none}
.js .pg-nav{display:grid;place-items:center;position:absolute;top:50%;transform:translateY(-50%);z-index:2;width:48px;height:48px;padding-bottom:4px;border-radius:50%;border:0;background:color-mix(in srgb,var(--bg) 70%,transparent);color:var(--white);font-size:1.8rem;line-height:1;cursor:pointer}
.pg-nav:hover{background:var(--cta);color:var(--on-cta)}
.pg-prev{left:14px}.pg-next{right:14px}
.pg-thumbs{display:none}
.js .pg-thumbs{display:flex;gap:10px;overflow-x:auto;padding:14px 4px 8px;scrollbar-width:thin}
.pg-thumb{position:relative;flex:none;width:136px;aspect-ratio:16/9;padding:0;border:2px solid var(--line);border-radius:12px;overflow:hidden;background:var(--bg2);cursor:pointer;opacity:.6;transition:opacity .2s,border-color .2s}
.pg-thumb img{width:100%;height:100%;object-fit:cover}
.pg-thumb:hover{opacity:1}
.pg-thumb[aria-current="true"]{opacity:1;border-color:var(--cta)}
.pg-play{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:34px;height:34px;border-radius:50%;background:var(--cta);color:var(--on-cta);display:grid;place-items:center;font-size:.85rem;padding-left:3px}
.pp-secs{display:grid;gap:20px}
.pp-sec h2{font-size:clamp(1.5rem,3vw,2rem);margin-bottom:.4em}
.pp-sec p{color:var(--cream);margin-bottom:.9em}
.pp-sec p:last-child{margin-bottom:0}
.pp-sec .post-lede{margin-bottom:.8em}
.pp-sec ul{margin-top:0}
@media (max-width:1000px){.post-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (hover:none){.swipe-hint{display:block;text-align:center;color:var(--muted);font-size:.85rem;margin-top:10px}}
@media (max-width:700px){
  body{font-size:16px}
  /* blur is expensive on phones, so use less of it */
  .panel::before{inset:-20px;filter:blur(calc(var(--blur,8px) * .6)) brightness(.5) saturate(1.1)}
  .slide{filter:blur(2px)}
  .panel{padding:56px 5vw 48px}
  .panel.top{padding-top:104px;min-height:0}
  .sj-header{padding:12px 4vw}
  .sj-mark{height:52px}
  .sj-mark img{height:52px}
  .hero{min-height:520px}
  .card{padding:20px}
  .fslide,.entry{padding:0}
  .fslide,.fmatch{width:80%}
  .ftimer{right:10%}
  .fnav .prev{left:2px}
  .fnav .next{right:2px}
  .fnav button{width:34px;height:34px;top:calc(50% - 17px)}
  .thumb{margin:-20px -20px 16px}
  .fbody,.entry .body{padding:18px 18px 20px}
  .entry h3,.fbody h3{font-size:1.25rem}
  /* phones: no expandable sections on a card (the project page has it all), and pressing the card opens that page */
  .tablist,.tabpanel:not(:first-child){display:none}
  .tabpanel{height:auto;overflow:visible;padding:0}
  .tabs{margin-top:0}
  .btn.ico.view-project{width:46px;padding:0;display:grid}
  .btn.ico.view-project img{display:block}
  .btn.ico.view-project span{display:none}
  .btn.ico.view-project::after{display:block}
  .entry,.fslide{cursor:pointer}
  .timeline{padding-left:18px}
  .tl{padding-left:18px}
  .tl-item::before{left:-33px}
  .tl-year{top:74px;margin-left:-25px}
  .tl-year span{font-size:1.05rem;padding:2px 14px}
  .timeline .card::before{left:-33px}
  .mc{left:10px;bottom:10px;padding:6px 12px 6px 8px;gap:8px}
  .mc img{width:24px;height:24px}
  .mc b{font-size:1.9rem;min-width:52px;height:46px}
  /* content hidden on a phone until the button is pressed */
  .m-more{display:none}
  .card.open .m-more{display:block}
  .post-grid{grid-template-columns:1fr;gap:28px}
  .post-sort{width:100%;justify-content:space-between;gap:10px}
  .post-search{width:100%}
  .seg button{padding:0 16px}
  .m-toggle{display:inline-block;padding:9px 18px;font-size:.92rem;margin:10px 0 4px}
  .toggle{padding:9px 18px;font-size:.92rem}
  /* tools: compact two-column grid */
  .skills{grid-template-columns:1fr 1fr;gap:10px}
  .skill{grid-template-columns:1fr;gap:8px;padding:14px}
  .skill .ico{width:44px;height:44px;border-radius:12px}
  .skill .ico img{width:24px;height:24px}
  .skill h4{font-size:1rem}
  .skill p{display:none}
  .group{margin-top:26px}
  .two{gap:20px}
  .btn{padding:12px 24px}
  .lb{grid-template-columns:minmax(0,1fr)}
  .lb-stage{grid-column:1;padding:60px 8px 8px}
  .lb-nav{position:absolute;top:50%;transform:translateY(-50%);z-index:2;background:color-mix(in srgb,var(--bg) 70%,transparent)}
  .lb-prev{left:8px}.lb-next{right:8px}
  .lb-bar{padding:8px 16px 16px}
  /* the Metacritic badge stays beside the title, smaller: logo and score (the platform is in its hover label) */
  .pp-head{column-gap:12px}
  .pp-head .mc{padding:5px 8px 5px 6px;gap:6px;border-radius:14px}
  .pp-head .mc img{width:20px;height:20px}
  .pp-head .mc b{font-size:1.5rem;min-width:42px;height:38px;border-radius:10px;padding:0 6px}
  .pp-head .mc small{display:none}
  .pp-sub{gap:6px}
  .pp-sep{margin:0 1px}
  .card ul.pp-sub{gap:5px}
  .card .plat{height:31px}
  .card .plat:not(.tech){flex-basis:31px}
  .card .plat img{width:17px;height:17px}
  .card .plat.tech{width:auto;gap:5px;padding:0 8px 0 6px}
  .plat{width:34px;height:34px;border-radius:10px}
  .plat img{width:18px;height:18px}
  .plat.tech img{width:20px;height:20px}
  .plat.tech{gap:6px;padding:0 10px 0 7px}
  .plat.tech span{font-size:.92rem}
  .pg-item{border-radius:16px}
  .js .pg-nav{width:40px;height:40px;font-size:1.5rem}
  .pg-prev{left:8px}.pg-next{right:8px}
  .pg-thumb{width:104px}
}
/* the CV's download button: a small .btn pill tucked into the paper's top corner. On phones there is no room beside
   the name, so it sits at the top of the paper, on the right, above it. */
.paper{position:relative}
.pdf-btn{position:absolute;top:14px;right:14px;padding:7px 14px 7px 16px;font-size:.85rem;box-shadow:0 3px 0 var(--cta-dark)}
.pdf-btn svg{width:1.05em;height:1.05em;fill:currentColor;vertical-align:-.17em;margin-left:6px}
.pdf-btn:hover{transform:translateY(-2px);box-shadow:0 5px 0 var(--cta-dark)}
@media(max-width:700px){.pdf-btn{position:static;display:table;margin:-10px -10px 14px auto}}
.paper .cv-links{display:none}
/* printing, and the cv.pdf made by tools/make_cv_pdf.mjs: just the CV, laid out like Samuel's CV in Google Drive (Arial,
   centred name, plain blue headings, tight lists) so it fits on two sides of A4. No site chrome, skills charts or button.
   The blues are the Drive CV's own (heading #2e74b5, link #0563c1), not site tokens: this is a document, not the site. */
@page{size:A4;margin:13mm 15mm}
@media print{
  .sj-header,#sj-header,#sj-footer,.hero,footer,.cv-actions,#tools,.skip-link,.noscript{display:none!important}
  .panel::before,.panel::after{display:none}.panel{padding:0!important;background:none!important;min-height:0!important}
  :root{color-scheme:light}.wrap{max-width:none;padding:0}html,body{background:#fff!important}
  .reveal{opacity:1!important;transform:none!important}
  .paper{box-shadow:none;border-radius:0;padding:0;background:#fff;color:#000;font-family:Arial,'Liberation Sans',Helvetica,sans-serif;font-size:10.5pt;line-height:1.3}
  .paper h1,.paper h2,.paper h3{font-family:inherit;font-weight:400;color:#2e74b5;text-transform:none;text-wrap:wrap}
  .paper h1{font-size:20pt;text-align:center;line-height:1.15}
  .paper .sub{text-align:center;font-weight:700;color:#000;margin:1pt 0 0}
  .paper .loc,.paper .social-icons{display:none}
  .paper .cv-links{display:block;text-align:center;margin:1pt 0 0}
  .paper a{color:#0563c1}
  .paper h2{font-size:13.5pt;border:0;padding:0;margin:9pt 0 2pt;break-after:avoid}
  .paper h3{font-size:11.5pt;margin:7pt 0 0;break-after:avoid}
  .paper .when{color:#000;margin:0 0 1pt;break-after:avoid}
  .paper p{margin:0 0 3pt}
  .paper .small{font-size:inherit;color:#000}
  .paper p.small{margin:2pt 0 0;break-after:avoid}
  .paper ul{display:block;padding-left:16pt;margin:1pt 0 2pt}
  .paper li{margin:0 0 1.5pt;break-inside:avoid}
  .paper li::marker{color:#000}
  .paper ul.small{list-style:circle;padding-left:30pt}
  .paper p.small.note-top{text-align:center;margin-top:14pt}
}

/* Home cards: compact. Shorter picture, small one-line title, description clamped to three lines */
.hc{padding:18px}
.hc .thumb{height:140px;margin:-18px -18px 14px}
.card.hc h3{display:block;font-size:1.05rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-bottom:2px}
.card.hc ul.pp-sub{margin:0 0 6px}
.card.hc p.roleline{font-size:.9rem;margin:0 0 6px}
.card.hc p.hc-text{font-size:.9rem;line-height:1.4;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
