/* labs.chrisdemetriou.com in chrisdemetriou.com's "Your week" look: same tokens, fonts,
   header and nav, with projects laid out like GitHub repositories. Static, no scripts.
   Light, like the main site's default. Dark (and the rest of the Display panel) needs a
   script, which Labs' CSP doesn't allow yet. */
:root{
  color-scheme:light;
  --bg:#FFF7EC;
  --surface:#FFFFFF;
  --surface-2:#F5EBDD;
  --border:#E3D6C3;
  --ink:#23201C;             /* 15:1 */
  --ink-muted:#5E564C;       /* 6.9:1 */
  --accent:#B53A1E;          /* tomato */
  --accent-hover:#93301A;
  --accent-ink:#FFFFFF;      /* 5.9:1 on --accent */
  --link-line:#B53A1E;
  --edge:#23201C;            /* the chunky outlines */
  --shadow:#23201C;          /* the hand-cut offset shadows */
  --blk-ink:#23201C;
  --c1:#FBD9CC; --c2:#FFE08A; --c3:#DCE8FF; --c4:#E9E0FF;
  --done-ink:#1F6E52; --sticker-live:#D3EEE3;
  --hover:#F5EBDD;
  --side: var(--ink);            /* Creative uses the theme text colour. */
  --font:'Atkinson Hyperlegible',system-ui,-apple-system,'Segoe UI',sans-serif;
  --head:'Bricolage Grotesque',system-ui,-apple-system,'Segoe UI',sans-serif;
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-padding-top:90px}
html,body{margin:0;padding:0;background:var(--bg);color:var(--ink)}
body{font-family:var(--font);font-size:18px;line-height:1.6;-webkit-font-smoothing:antialiased;overflow-x:hidden}
a{color:var(--ink);text-decoration-color:var(--link-line);text-decoration-thickness:2px;text-underline-offset:4px}
a:hover{text-decoration-color:var(--accent)}
a:focus-visible,summary:focus-visible{outline:3px solid var(--accent);outline-offset:3px;border-radius:6px}
.container{width:100%;max-width:1200px;margin:0 auto;padding:0 clamp(16px,4vw,40px)}
.sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.skip{position:absolute;left:-9999px;top:8px;z-index:900;padding:10px 14px;background:var(--accent);color:var(--accent-ink);font-weight:700;border-radius:10px}
.skip:focus{left:16px}
.label{font-weight:700;font-size:15px;color:var(--ink-muted)}
h1,h2,h3,h4{font-family:var(--head)}

/* ── Header: photo + name, nav (same as chrisdemetriou.com) ── */
.masthead{position:sticky;top:0;z-index:500;background:var(--bg);border-bottom:2px solid var(--border)}
.masthead .container{position:relative;display:flex;align-items:center;gap:8px 20px;min-height:76px}
.me{display:flex;align-items:center;gap:12px;flex:none;height:44px;color:var(--ink);text-decoration:none}
.me img{width:44px;height:44px;border-radius:50%;object-fit:cover;border:2px solid var(--edge)}
.me b{display:block;font-family:var(--head);font-weight:800;font-size:19px;line-height:1.15;font-variation-settings:"opsz" 24}
.me small{display:block;font-size:14px;line-height:1.3;color:var(--ink-muted)}
.section-nav{margin-left:auto}
.section-nav ul{display:flex;flex-wrap:wrap;align-items:center;gap:2px;list-style:none;margin:0;padding:0}
.section-nav a,.section-nav summary{display:inline-flex;align-items:center;gap:6px;min-height:40px;padding:6px 12px;font-weight:700;font-size:16px;color:var(--ink);text-decoration:none;border-radius:10px;cursor:pointer}
.section-nav a:hover,.section-nav summary:hover{background:var(--hover)}
.section-nav a.current{background:var(--c2);color:var(--blk-ink)}
/* Creative menu: a native <details>, no script */
.section-nav summary{list-style:none}
.section-nav summary::-webkit-details-marker{display:none}
.section-nav summary::after{content:"";width:7px;height:7px;border-right:2px solid currentColor;border-bottom:2px solid currentColor;transform:translateY(-2px) rotate(45deg);transition:transform .15s ease}
.section-nav details[open] summary::after{transform:translateY(2px) rotate(-135deg)}
.nav-group{position:relative}
.nav-group ul{position:absolute;top:calc(100% + 8px);left:0;z-index:600;display:block;min-width:190px;margin:0;padding:6px;background:var(--surface);border:2px solid var(--edge);border-radius:14px;box-shadow:4px 4px 0 var(--shadow)}
.nav-group ul a{display:flex;width:100%;min-height:44px}
/* the business path ends on Contact; Creative sits after it, set apart (as on the homepage) */
.section-nav li.nav-cta>a{margin-left:4px;padding:5px 14px;color:var(--accent-ink);background:var(--accent);border:2px solid var(--edge);box-shadow:3px 3px 0 var(--edge)}
.section-nav li.nav-cta>a:hover{background:var(--accent-hover)}
.section-nav .nav-side{margin-left:10px;padding-left:10px;border-left:2px dashed var(--border)}
.section-nav .nav-side>details>summary{color:var(--side)}
.nav-side ul{left:auto;right:0}
/* Two rows on narrow screens. No script here, so the name row's height is fixed and the
   header sticks that far up: the name row scrolls away, the nav row stays. */
@media (max-width:1080px){
  .masthead{top:-58px}
  .masthead .container{flex-wrap:wrap;min-height:0;padding-top:10px}
  .section-nav{order:3;flex-basis:calc(100% + 10px);margin:0 0 4px -10px}
  html{scroll-padding-top:70px}
}
@media (max-width:760px){
  .masthead{top:-52px}
  .me{height:38px}
  .me img{width:38px;height:38px}
  .me small{display:none}
  .section-nav .nav-wide{display:none}
  .section-nav a,.section-nav summary{padding:6px 8px}
  .section-nav li.nav-cta>a{padding:4px 10px}
  .section-nav .nav-side{margin-left:8px;padding-left:4px}
  .nav-group{position:static}
  .nav-group ul{left:16px;right:16px;min-width:0}
}

@media (max-width:380px){
  .section-nav a,.section-nav summary{padding:6px 6px;font-size:15px}
  .section-nav li.nav-cta>a{margin-left:2px;padding:4px 8px}
  .section-nav .nav-side{margin-left:6px;padding-left:2px}
}

/* ── Header block ── */
.record-header .container{padding-top:clamp(32px,5vw,56px);padding-bottom:clamp(24px,4vw,40px)}
.record-name{margin:0 0 12px;font-weight:800;font-size:clamp(2.6rem,5.6vw,4.2rem);line-height:.98;letter-spacing:-.018em;font-variation-settings:"opsz" 96,"wdth" 92}
.record-standfirst{margin:0;max-width:52ch;font-size:1.2rem;line-height:1.55;color:var(--ink-muted)}

.band{padding:clamp(36px,5vw,64px) 0;border-top:2px dashed var(--border)}
.count{display:inline-block;min-width:22px;padding:1px 7px;border-radius:999px;background:var(--surface-2);color:var(--ink);font-size:13px;text-align:center}

/* ── A project, laid out like a GitHub repository ── */
.repo{margin:0 0 28px;background:var(--surface);border:2px solid var(--edge);border-radius:22px;box-shadow:8px 8px 0 var(--shadow);overflow:hidden}
.repo:last-child{margin-bottom:0}
.repo-head{display:flex;flex-wrap:wrap;align-items:center;gap:10px 14px;padding:18px clamp(16px,2.4vw,26px);border-bottom:2px dashed var(--border)}
.repo-name{margin:0;font-weight:800;font-size:clamp(1.4rem,2.6vw,1.8rem);line-height:1.15;letter-spacing:-.01em}
.repo-owner{color:var(--ink-muted);font-weight:500}
.repo-name a{color:var(--ink);text-decoration:none}
.repo-name a:hover{text-decoration:underline;text-decoration-color:var(--accent)}
/* Live / Demo stickers */
.pill{display:inline-block;padding:4px 10px;font-family:var(--font);font-weight:700;font-size:14px;line-height:1.2;color:var(--blk-ink);background:var(--sticker-live);border:2px solid var(--blk-ink);border-radius:999px;transform:rotate(3deg)}
.pill-demo{background:var(--c2);transform:rotate(-3deg)}
.btn{margin-left:auto;display:inline-flex;align-items:center;gap:6px;padding:12px 20px;font-family:var(--font);font-weight:700;font-size:17px;line-height:1.2;color:var(--accent-ink);background:var(--accent);border:2px solid var(--edge);border-radius:14px;box-shadow:4px 4px 0 var(--edge);text-decoration:none;white-space:nowrap;transition:transform .12s ease,box-shadow .12s ease,background-color .12s ease}
.btn:hover{background:var(--accent-hover);transform:translate(-1px,-1px);box-shadow:5px 5px 0 var(--edge)}
.btn:active{transform:translate(3px,3px);box-shadow:1px 1px 0 var(--edge)}
@media (max-width:560px){.btn{margin-left:0;width:100%;justify-content:center}}

.repo-grid{display:grid;grid-template-columns:minmax(0,1fr) 290px;gap:0}
.repo-main{padding:clamp(16px,2.4vw,26px);min-width:0}
.repo-about{padding:clamp(16px,2.4vw,26px);border-left:2px dashed var(--border)}
@media (max-width:820px){.repo-grid{grid-template-columns:1fr}.repo-about{border-left:0;border-top:2px dashed var(--border)}}

.shot{display:block;overflow:hidden;border:2px solid var(--edge);border-radius:14px;background:var(--bg)}
.shot img{display:block;width:100%;height:auto;aspect-ratio:16/10;object-fit:cover;object-position:top}
.shot:hover{border-color:var(--accent)}

/* Topic tags */
.topics{list-style:none;margin:18px 0 0;padding:0;display:flex;flex-wrap:wrap;gap:8px}
.topics li{font-weight:700;font-size:14px;line-height:1.2;color:var(--ink);border:2px solid var(--border);border-radius:999px;padding:5px 12px}

.about-h{margin:0 0 10px;font-family:var(--font)}
.about-h~.about-h{margin-top:22px}
.about-desc{margin:0 0 12px;font-size:1rem;line-height:1.6}
.about-site{margin:0 0 12px;font-weight:700;font-size:.95rem;word-break:break-word}
.about-links{list-style:none;margin:0;padding:0;display:grid;gap:6px;font-size:.95rem}
.lang-bar{display:block;width:100%;height:8px;border-radius:4px;overflow:hidden}
.lang-list{list-style:none;margin:10px 0 0;padding:0;display:flex;flex-wrap:wrap;gap:6px 14px;font-size:.88rem}
.lang-list li{display:inline-flex;align-items:center;gap:6px}
.dot{width:8px;height:8px;flex:none}
.lang-name{color:var(--ink);font-weight:700}
.lang-pct{color:var(--ink-muted)}
.updated{margin:22px 0 0}

/* ── Architecture drawing ── */
.arch{padding:clamp(16px,2.4vw,26px);border-top:2px dashed var(--border)}
.arch-h{margin:0 0 16px;font-family:var(--font)}
.arch-flow{display:grid;grid-template-columns:minmax(0,1fr) 96px minmax(0,1fr) 96px minmax(0,1fr);align-items:stretch}
.tier{padding:12px;background:var(--bg);border:2px solid var(--border);border-radius:16px}
.tier-label{display:inline-block;margin:0 0 10px;padding:3px 10px;font-weight:700;font-size:14px;color:var(--blk-ink);background:var(--c3);border:2px solid var(--blk-ink);border-radius:10px}
.nodes{list-style:none;margin:0;padding:0;display:grid;gap:8px}
.node{display:grid;gap:2px;padding:9px 11px;background:var(--surface);border:2px solid var(--border);border-left:5px solid var(--accent);border-radius:10px}
.node strong{font-weight:700;color:var(--ink);font-size:.98rem}
.node span{color:var(--ink-muted);font-size:.88rem;line-height:1.45}
/* A wire: a line with an arrowhead, its protocol written on it. */
.wire{position:relative;display:flex;align-items:center;justify-content:center}
.wire::before{content:"";position:absolute;left:6px;right:10px;top:50%;border-top:2px dashed var(--link-line)}
.wire::after{content:"";position:absolute;right:4px;top:50%;margin-top:-6px;border:6px solid transparent;border-left:8px solid var(--link-line);border-right:0}
.wire-label{position:relative;top:-24px;max-width:88px;padding:0 2px;font-weight:700;font-size:12px;line-height:1.35;color:var(--link-line);text-align:center}
@media (max-width:820px){
  .arch-flow{grid-template-columns:1fr}
  .wire{height:52px;justify-content:flex-start;padding-left:36px}
  .wire::before{left:20px;right:auto;top:4px;bottom:12px;border-top:0;border-left:2px dashed var(--link-line)}
  .wire::after{left:15px;right:auto;top:auto;bottom:3px;margin-top:0;border:6px solid transparent;border-top:8px solid var(--link-line);border-bottom:0}
  .wire-label{top:0;max-width:none;padding:0 4px}
}

/* ── Overview (/): fits on one screen ── */
.labs-head .container{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:14px 40px;align-items:end;padding-top:clamp(22px,3.4vw,40px);padding-bottom:clamp(18px,2.6vw,28px)}
.labs-head .record-name{margin-bottom:10px}
.stats .short{display:none}
.stats{display:grid;grid-template-columns:repeat(4,auto);gap:6px 30px;margin:0}
.stats div{display:grid;gap:2px}
.stats dt{font-weight:700;font-size:14px;color:var(--ink-muted)}
.stats dd{margin:0;font-family:var(--head);font-weight:800;font-size:1.7rem;line-height:1.1;color:var(--ink)}
@media (max-width:820px){.labs-head .container{grid-template-columns:1fr}.stats{grid-template-columns:auto auto auto 1fr;gap:4px 22px}.stats dd{font-size:1.25rem;white-space:nowrap}}
@media (max-width:640px){.stats .long{display:none}.stats .short{display:inline}.stats dd{font-size:1.1rem}}
.labs.band{padding:clamp(18px,2.6vw,28px) 0 clamp(40px,5vw,64px)}

/* Technology filters: radio buttons + :has(), no script. Browsers without :has() show everything. */
.filters{border:0;margin:0 0 18px;padding:0;min-width:0}
.filters legend{padding:0;margin-bottom:10px}
.filter-row{display:flex;flex-wrap:wrap;gap:8px}
.filter-row label{display:inline-flex;align-items:center;gap:6px;font-weight:700;font-size:15px;line-height:1.2;color:var(--ink);border:2px solid var(--border);border-radius:999px;padding:7px 13px;cursor:pointer;white-space:nowrap;transition:border-color .15s ease,background-color .15s ease}
.filter-row label:hover{border-color:var(--ink-muted)}
.filter-row input:checked+label{color:var(--blk-ink);background:var(--c2);border-color:var(--blk-ink)}
.filter-row input:checked+label .count{background:rgba(35,32,28,.12);color:var(--blk-ink)}
.filter-row input:focus-visible+label{outline:3px solid var(--accent);outline-offset:3px}
@media (max-width:640px){.filter-row{flex-wrap:nowrap;overflow-x:auto;padding-bottom:6px;margin:0 calc(-1*clamp(16px,4vw,40px));padding-left:clamp(16px,4vw,40px);padding-right:clamp(16px,4vw,40px);scrollbar-width:none}.filter-row::-webkit-scrollbar{display:none}}

/* Pinned cards */
.pcards{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,200px),1fr));gap:18px}
.pcard{display:flex;flex-direction:column;min-width:0;overflow:hidden;background:var(--surface);border:2px solid var(--edge);border-radius:18px}
.pcard-shot{display:block;border-bottom:2px solid var(--edge);background:var(--bg)}
.pcard-shot img{display:block;width:100%;height:auto;aspect-ratio:5/2;object-fit:cover;object-position:top}
.pcard-body{display:flex;flex-direction:column;gap:8px;padding:14px 15px 16px;flex:1;min-width:0}
.pcard-name{margin:0;display:flex;align-items:center;flex-wrap:wrap;gap:6px 10px;font-weight:800;font-size:1.15rem;line-height:1.2;overflow-wrap:break-word;min-width:0}
.pcard-name a{color:var(--ink);text-decoration:none}
.pcard-name a:hover{text-decoration:underline;text-decoration-color:var(--accent)}
.pcard-desc{margin:0;color:var(--ink-muted);font-size:.92rem;line-height:1.45;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.pcard-meta{margin:0;display:flex;flex-wrap:wrap;gap:2px 12px;font-size:.82rem;color:var(--ink-muted)}
.pcard-lang{display:inline-flex;align-items:center;gap:6px;color:var(--ink);font-weight:700}
.pcard-tags{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:6px}
.pcard-tags li{font-weight:700;font-size:13px;line-height:1.2;color:var(--ink);border:2px solid var(--border);border-radius:999px;padding:3px 9px}
.pcard-tags li.more{color:var(--ink-muted)}
.pcard-actions{margin:auto 0 0;padding-top:6px;display:flex;flex-wrap:wrap;align-items:center;gap:10px 14px}
.btn.btn-sm{margin-left:0;padding:8px 12px;font-size:15px;box-shadow:3px 3px 0 var(--edge)}
.pcard-more{font-weight:700;font-size:.92rem;white-space:nowrap}
/* Phones: slim rows, a small picture beside the text, so several fit on one screen. */
@media (max-width:640px){
  .pcards{grid-template-columns:1fr;gap:14px}
  .pcard{display:grid;grid-template-columns:104px minmax(0,1fr);align-items:start}
  .pcard-shot{border-bottom:0;border-right:2px solid var(--edge);height:100%}
  .pcard-shot img{aspect-ratio:auto;height:100%;min-height:100px;object-position:50% 35%}
  .pcard-updated{display:none}
  .pcard-body{padding:12px;gap:6px}
  .pcard-tags{display:none}
}

/* ── Project pages (/<slug>/) ── */
.crumbs{display:flex;justify-content:space-between;align-items:center;gap:12px;padding-top:18px;padding-bottom:6px;font-weight:700;font-size:15px}
.crumbs a{text-decoration:none}
.crumbs a:hover{text-decoration:underline}
.repo-page.band{padding-top:14px;border-top:0}
.next-project{margin:30px 0 0;display:flex;justify-content:flex-end;align-items:center;gap:12px}
.next-project a{font-family:var(--head);font-weight:800;font-size:1.3rem;text-decoration:none}
.next-project a:hover{text-decoration:underline;text-decoration-color:var(--accent)}

/* ── Footer: same as chrisdemetriou.com ── */
footer{border-top:2px dashed var(--border);padding:24px 0 34px}
.foot-line{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:10px;font-size:15px;color:var(--ink-muted)}
.foot-line a{color:var(--ink-muted);text-decoration:none}
.foot-line a:hover{color:var(--ink);text-decoration:underline}

/* 404 page */
.eyebrow{display:inline-block;margin:32px 0 12px;padding:4px 12px;font-weight:700;color:var(--blk-ink);background:var(--c2);border:2px solid var(--blk-ink);border-radius:10px;transform:rotate(-2deg)}
.lost h1{margin:0 0 12px;font-weight:800;font-size:clamp(2.2rem,5vw,3.4rem);line-height:1.05}
.lost p{color:var(--ink-muted)}

/* Touch screens up to tablet size: thumb-sized targets. */
@media (max-width:900px){
  .pcard-name a,.repo-name a{display:inline-block;padding:6px 0}
  .pcard-more{display:inline-block;padding:8px 0}
  .about-site a,.about-links a{display:inline-block;padding:6px 0}
  .crumbs a{display:inline-block;padding:8px 0}
  .next-project a{display:inline-block;padding:6px 0}
  .foot-line a{display:inline-block;padding:8px 0}
}
/* ── Micro-behaviours: CSS only (Labs runs no script), off when the device asks for less motion ── */
@keyframes cd-rise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:no-preference){
  .btn{transition:transform .2s cubic-bezier(.34,1.56,.64,1),box-shadow .2s ease,background-color .15s ease}
  .pcard,.repo{transition:transform .25s cubic-bezier(.2,.7,.2,1),box-shadow .25s ease}
  .pcard-shot img,.shot img{transition:transform .6s cubic-bezier(.2,.7,.2,1)}
  .pill,.filter-row label{transition:transform .35s cubic-bezier(.34,1.56,.64,1),background-color .15s ease,border-color .15s ease}
  .record-name,.record-standfirst,.stats,.crumbs{animation:cd-rise .6s cubic-bezier(.2,.7,.2,1) both}
  .record-standfirst{animation-delay:.08s}.stats{animation-delay:.16s}
  .pcards>li,.repo{animation:cd-rise .6s cubic-bezier(.2,.7,.2,1) both}
  .pcards>li:nth-child(2){animation-delay:.06s}.pcards>li:nth-child(3){animation-delay:.12s}.pcards>li:nth-child(4){animation-delay:.18s}.pcards>li:nth-child(5){animation-delay:.24s}.pcards>li:nth-child(n+6){animation-delay:.3s}
}
@media (hover:hover) and (prefers-reduced-motion:no-preference){
  .pcard:hover{transform:translate(-3px,-3px);box-shadow:6px 6px 0 var(--shadow)}
  .pcard:hover .pcard-shot img{transform:scale(1.04)}
  .pcard:hover .pill{transform:rotate(-6deg) scale(1.08)}
  .shot:hover img{transform:scale(1.02)}
  .filter-row label:hover{transform:rotate(-2deg)}
}
@media (prefers-reduced-motion:reduce){*,*::before,*::after{transition-duration:.01ms !important;animation:none !important}}
