/* ==========================================================================
   Narek Khurshudyan, Unity Developer
   Dark-first, one accent, stacked skill cards, point-cloud avatar hero.
   ========================================================================== */

:root {
    --bg: #0a0c11;
    --bg-2: #0f1218;
    --bg-3: #161a24;
    --fg: #eef0f6;
    --fg-2: #a9b0c1;
    --fg-3: #6d7585;
    --line: rgba(255, 255, 255, 0.08);
    --line-2: rgba(255, 255, 255, 0.18);
    --accent: #8da2ff;
    --accent-2: #5ee6c8;
    --accent-soft: rgba(141, 162, 255, 0.12);
    --accent-line: rgba(141, 162, 255, 0.55);
    --glow: rgba(141, 162, 255, 0.28);
    --glow-2: rgba(94, 230, 200, 0.12);
    --card: rgba(255, 255, 255, 0.025);
    --card-hover: rgba(255, 255, 255, 0.045);
    --chip: rgba(255, 255, 255, 0.03);
    --talk-top: #15171c;
    --glass: rgba(11, 13, 19, 0.74); /* panels over the curtain: dark glass */
    --shadow: 0 24px 60px -28px rgba(0, 0, 0, 0.75);
    --media-bg: #05060a;
    /* The portfolio's devices (phones, windows, a VR visor) are dark in
       both themes, like the real ones. */
    --device: #07080c;
    --device-shadow: 0 0 0 1px rgba(255, 255, 255, 0.07), 0 36px 70px -34px rgba(0, 0, 0, 0.9);
    /* The fit check's verdict colours: strong, partial, gap. */
    --ok: #5ee6c8;
    --warn: #f2c069;
    --bad: #ff7b8e;

    --font-display: "Bricolage Grotesque", "Inter", system-ui, sans-serif;
    --font-text: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

    --wrap: 1200px;
    --gutter: clamp(1.25rem, 4vw, 3rem);
    --radius: 20px;
    --radius-sm: 12px;

    color-scheme: dark;
}

:root[data-theme="light"] {
    --bg: #f5f6fa;
    --bg-2: #ffffff;
    --bg-3: #eceef5;
    --fg: #0f1219;
    --fg-2: #4a5263;
    --fg-3: #7a8294;
    --line: rgba(15, 18, 25, 0.09);
    --line-2: rgba(15, 18, 25, 0.2);
    --accent: #4457d6;
    --accent-2: #0d9f88;
    --accent-soft: rgba(68, 87, 214, 0.1);
    --accent-line: rgba(68, 87, 214, 0.5);
    --glow: rgba(68, 87, 214, 0.18);
    --glow-2: rgba(13, 159, 136, 0.1);
    --card: rgba(255, 255, 255, 0.72);
    --card-hover: #ffffff;
    --chip: rgba(15, 18, 25, 0.03);
    --talk-top: #ffffff;
    --glass: rgba(255, 255, 255, 0.8);
    --shadow: 0 24px 50px -30px rgba(15, 18, 25, 0.28);
    --media-bg: #0f1219;
    --device: #0c0e14;
    --device-shadow: 0 0 0 1px rgba(15, 18, 25, 0.08), 0 30px 60px -32px rgba(15, 18, 25, 0.45);
    --ok: #0d9f88;
    --warn: #b8791a;
    --bad: #d6455c;
    color-scheme: light;
}

/* Base ------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }

html {
    scroll-behavior: smooth;
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    background: var(--bg);
    color: var(--fg);
    font-family: var(--font-text);
    font-size: 1rem;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
}


/* Ambient background: two soft glows plus a dotted grid that fades out. */
body::before,
body::after {
    content: "";
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
}

body::before {
    background:
        radial-gradient(70rem 42rem at 85% -12%, var(--glow), transparent 60%),
        radial-gradient(46rem 32rem at -10% 35%, var(--glow-2), transparent 60%);
}

body::after {
    background-image: radial-gradient(var(--line-2) 1px, transparent 1.2px);
    background-size: 26px 26px;
    opacity: 0.45;
    -webkit-mask-image: linear-gradient(to bottom, #000 0, transparent 90vh);
    mask-image: linear-gradient(to bottom, #000 0, transparent 90vh);
}

main, .topbar, .footer { position: relative; z-index: 1; }

h1, h2, h3, h4, p, ul, ol, dl, dd { margin: 0; }
ul, ol { padding: 0; list-style: none; }
a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 0.18em; }
strong { font-weight: 600; color: var(--fg); }
button { font: inherit; color: inherit; }

.wrap {
    width: min(100% - 2 * var(--gutter), var(--wrap));
    margin-inline: auto;
}

.skip-link {
    position: absolute;
    left: 1rem;
    top: -3rem;
    z-index: 100;
    padding: 0.5rem 0.75rem;
    background: var(--fg);
    color: var(--bg);
    border-radius: 6px;
}
.skip-link:focus { top: 1rem; }

:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
}

/* Shared bits ------------------------------------------------------------ */

.pulse {
    position: relative;
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--accent-2);
    flex: 0 0 auto;
}
.pulse::after {
    content: "";
    position: absolute;
    inset: -4px;
    border-radius: 50%;
    border: 1px solid var(--accent-2);
    opacity: 0.7;
    animation: pulse-ring 2.2s ease-out infinite;
}
@keyframes pulse-ring {
    0% { transform: scale(0.5); opacity: 0.8; }
    100% { transform: scale(1.6); opacity: 0; }
}

/* Cards: hairline border, faint fill, pointer-following spotlight. */
.card {
    position: relative;
    overflow: hidden;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--card);
    transition: border-color 0.3s, background 0.3s, transform 0.3s;
}
.card::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background: radial-gradient(460px circle at var(--mx, 50%) var(--my, 0%), var(--accent-soft), transparent 45%);
    opacity: 0;
    transition: opacity 0.4s;
}
.card > * { position: relative; z-index: 1; }
.card:hover { border-color: var(--line-2); background: var(--card-hover); }
.card:hover::before { opacity: 1; }

/* Reveal on scroll (only applied once JS confirms IntersectionObserver). */
html.js-rv .rv {
    opacity: 0;
    transform: translateY(18px);
}
html.js-rv .rv.in {
    opacity: 1;
    transform: none;
    transition: opacity 0.65s ease, transform 0.65s cubic-bezier(0.2, 0.7, 0.2, 1);
}

.btn {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.8rem 1.35rem;
    border-radius: 999px;
    font-size: 0.94rem;
    font-weight: 500;
    text-decoration: none;
    border: 1px solid transparent;
    transition: background 0.2s, color 0.2s, border-color 0.2s, transform 0.2s, box-shadow 0.3s;
}
.btn:active { transform: translateY(1px); }
.btn--primary {
    background: var(--fg);
    color: var(--bg);
    box-shadow: 0 10px 30px -12px var(--glow);
}
.btn--primary:hover { background: var(--accent); color: #0a0c11; }
.btn--ghost { border-color: var(--line-2); color: var(--fg); }
.btn--ghost:hover { border-color: var(--fg); background: var(--card-hover); }

.tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.45rem;
}
.tags li {
    padding: 0.32rem 0.7rem;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: var(--chip);
    font-family: var(--font-mono);
    font-size: 0.74rem;
    letter-spacing: 0.01em;
    color: var(--fg-2);
    transition: border-color 0.2s, color 0.2s, background 0.2s;
}
.tags li:hover { border-color: var(--line-2); color: var(--fg); }
.tags--strong li {
    border-color: var(--accent-line);
    background: var(--accent-soft);
    color: var(--fg);
}

/* Top bar (floating pill) ----------------------------------------------- */

.topbar {
    position: fixed;
    top: 0.9rem;
    left: 0;
    right: 0;
    z-index: 50;
    pointer-events: none;
}

.topbar__inner {
    pointer-events: auto;
    position: relative;
    width: min(100% - 2 * var(--gutter), var(--wrap));
    margin-inline: auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.45rem 0.45rem 0.45rem 1rem;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: color-mix(in srgb, var(--bg-2) 72%, transparent);
    backdrop-filter: blur(18px) saturate(1.4);
    -webkit-backdrop-filter: blur(18px) saturate(1.4);
    box-shadow: var(--shadow);
}

.topbar__brand {
    display: inline-flex;
    align-items: center;
    gap: 0.65rem;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.94rem;
    letter-spacing: -0.01em;
}

.topbar__mark {
    display: grid;
    place-items: center;
    width: 2rem;
    height: 2rem;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--accent), var(--accent-2));
    color: #0a0c11;
    font-family: var(--font-display);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.02em;
}

.topbar__nav {
    display: flex;
    align-items: center;
    gap: 0.15rem;
}

.topbar__link {
    padding: 0.5rem 0.85rem;
    font-size: 0.88rem;
    color: var(--fg-2);
    text-decoration: none;
    border-radius: 999px;
    transition: color 0.2s, background 0.2s;
}
.topbar__link:hover { color: var(--fg); background: var(--card-hover); }
.topbar__link.is-active { color: var(--fg); background: var(--accent-soft); }
/* The way to the fit check, from anywhere on the page. */
.topbar__link--fit {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    color: var(--fg);
}
.topbar__link--fit::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent-2);
    box-shadow: 0 0 8px var(--glow-2);
}

.topbar__tools {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.theme-toggle,
.topbar__menu {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.3rem;
    height: 2.3rem;
    padding: 0;
    background: transparent;
    border: 1px solid var(--line);
    border-radius: 50%;
    cursor: pointer;
    transition: border-color 0.2s, background 0.2s;
}
.theme-toggle:hover, .topbar__menu:hover { border-color: var(--line-2); background: var(--card-hover); }

.theme-toggle__moon { display: none; }
:root[data-theme="light"] .theme-toggle__sun { display: none; }
:root[data-theme="light"] .theme-toggle__moon { display: block; }

/* The short CV, one click away wherever the page is (cv.js). */
.topbar__cv {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    height: 2.3rem;
    padding: 0 0.95rem 0 0.8rem;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: transparent;
    color: var(--fg-2);
    font-family: var(--font-text);
    font-size: 0.84rem;
    font-weight: 500;
    white-space: nowrap;
    cursor: pointer;
    transition: border-color 0.2s, background 0.2s, color 0.2s;
}
.topbar__cv svg { flex: none; color: var(--accent); }
.topbar__cv:hover { border-color: var(--line-2); background: var(--card-hover); color: var(--fg); }
.topbar__cv:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.topbar__menu { display: none; flex-direction: column; gap: 5px; }
.topbar__menu-bar {
    width: 16px;
    height: 1.5px;
    background: currentColor;
    border-radius: 2px;
    transition: transform 0.25s, opacity 0.25s;
}
.topbar__menu[aria-expanded="true"] .topbar__menu-bar:first-child { transform: translateY(3.25px) rotate(45deg); }
.topbar__menu[aria-expanded="true"] .topbar__menu-bar:last-child { transform: translateY(-3.25px) rotate(-45deg); }

/* Hero ------------------------------------------------------------------- */

/* Two columns: the text on the left, the head and its chat on the right.
   The name sits level with the face so the two read as one person. */
.hero {
    position: relative; /* the curtain's canvas is a full-bleed layer behind everything here */
    padding-block: clamp(5.5rem, 7vw, 6.25rem) clamp(3rem, 6vw, 5rem);
    overflow-x: clip; /* the head's canvas is wider than its column; never a sideways scroll */
}

/* The name and the title are their own block above the rest of the text,
   so on a phone the head and its chat can sit right under the name. The
   two panels share the last row, top to top and the same width: the fit
   check under the text, the chat under the head (user, 2026-09-24). The
   chat grows down with its conversation up to --talk-max (chat.js sets it
   so a full chat still ends above the fold); the row keeps that much room
   from the start, so nothing below it moves while the head types. */
.hero__grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-rows: auto 1fr minmax(calc(var(--talk-max, 22rem) + 0.5rem), auto); /* + the panels' margin */
    grid-template-areas:
        "head visual"
        "copy visual"
        "fit  talk";
    gap: 1.25rem clamp(2rem, 5vw, 5rem);
    align-items: start;
}

.hero__head {
    grid-area: head;
    position: relative;
    z-index: 1; /* above the head's canvas wherever the two meet */
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    padding-top: clamp(0rem, 4.5vw, 4.25rem);
}

.hero__copy {
    grid-area: copy;
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 1.25rem;
}

/* The curtain runs on behind the text column: a soft pool of the page's own
   colour under the text keeps it readable without a visible box. */
.hero__head::before,
.hero__copy::before {
    content: "";
    position: absolute;
    inset: -3rem -4rem;
    z-index: -1;
    background: radial-gradient(closest-side, color-mix(in srgb, var(--bg) 72%, transparent), color-mix(in srgb, var(--bg) 40%, transparent) 60%, transparent);
    pointer-events: none;
}

/* Entrance: the text and the fit panel fade in as one block (opacity only,
   nothing moves, nothing gets re-composited); the head is its own
   entrance, coming through the curtain, and the bubble stays put. */
.hero__head.fade, .hero__copy.fade, .fitbox.fade { opacity: 0; }
.hero__head.fade.in, .hero__copy.fade.in, .fitbox.fade.in { opacity: 1; transition: opacity 0.7s ease; }

.hero__title {
    font-family: var(--font-display);
    font-variation-settings: "opsz" 96;
    font-weight: 700;
    font-size: clamp(2.3rem, 4.4vw, 3.6rem);
    line-height: 1;
    letter-spacing: -0.04em;
    color: var(--fg);
}

/* The three titles, in the site's own order; a line breaks only between
   two of them. */
.hero__role {
    margin-top: -0.55rem;
    font-family: var(--font-display);
    font-variation-settings: "opsz" 48;
    font-weight: 500;
    font-size: clamp(1.02rem, 1.6vw, 1.32rem);
    letter-spacing: -0.02em;
    line-height: 1.25;
    text-wrap: balance;
    background: linear-gradient(95deg, var(--accent), var(--accent-2));
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

.hero__role > span { white-space: nowrap; }
.hero__role > .hero__sep {
    margin-inline: 0.12em;
    font-weight: 300;
    color: var(--fg-3);
    -webkit-text-fill-color: var(--fg-3);
}

/* The summary: one plain paragraph. */
.hero__lead {
    max-width: 52ch;
    font-size: clamp(0.98rem, 1.25vw, 1.08rem);
    line-height: 1.55;
    color: var(--fg-2);
}

/* The job fit check: a panel of its own under the text, apart from the
   chat (user decision, 2026-09-23). It is the hero's call to action, so it
   carries the accent: a soft wash, a lit border, a live dot. */
.fitbox {
    grid-area: fit;
    position: relative;
    z-index: 1;
    width: 100%;
    margin-top: 0.5rem;
    padding: 1.05rem 1.1rem 0.95rem;
    border: 1px solid var(--accent-line);
    border-radius: var(--radius);
    background:
        radial-gradient(120% 90% at 0% 0%, color-mix(in srgb, var(--accent) 13%, transparent), transparent 60%),
        linear-gradient(180deg, var(--card-hover), var(--card)),
        var(--glass);
    -webkit-backdrop-filter: blur(16px) saturate(1.3);
    backdrop-filter: blur(16px) saturate(1.3);
    box-shadow: 0 24px 60px -34px var(--glow);
    scroll-margin-top: 6rem;
}
.fitbox--flash { animation: fitbox-flash 1.2s ease-out; }
@keyframes fitbox-flash {
    0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 55%, transparent), 0 24px 60px -34px var(--glow); }
    100% { box-shadow: 0 0 0 14px transparent, 0 24px 60px -34px var(--glow); }
}

.fitbox__kicker {
    display: flex;
    margin-bottom: 0.85rem;
    align-items: center;
    gap: 0.5rem;
    font-family: var(--font-mono);
    font-size: 0.68rem;
    font-weight: 400;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--accent-2);
}
.fitbox__spark {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--accent-2);
    animation: talk-dot 2.4s ease-out infinite;
}

.fitbox__form {
    display: flex;
    align-items: flex-end;
    gap: 0.55rem;
    padding: 0.3rem 0.3rem 0.3rem 0.85rem;
    border: 1px solid var(--line-2);
    border-radius: 16px;
    background: var(--bg-2);
    transition: border-color 0.2s, box-shadow 0.2s;
}
.fitbox__form:focus-within {
    border-color: var(--accent-line);
    box-shadow: 0 0 0 3px var(--accent-soft);
}
.fitbox__icon { flex: 0 0 auto; align-self: center; color: var(--fg-3); }
.fitbox__form:focus-within .fitbox__icon { color: var(--accent); }
.fitbox__input {
    flex: 1 1 auto;
    min-width: 0;
    max-height: 7.5rem;
    margin: 0;
    padding: 0.62rem 0;
    border: 0;
    background: transparent;
    color: var(--fg);
    font: inherit;
    font-size: 0.95rem;
    line-height: 1.45;
    resize: none;
    overflow-y: auto;
    scrollbar-width: thin;
    field-sizing: content;
}
.fitbox__input::placeholder { color: var(--fg-3); }
.fitbox__input:focus { outline: none; }
.fitbox__input[readonly] { color: var(--fg-2); }
.fitbox__go {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    height: 2.55rem;
    padding: 0 1.1rem;
    border: 0;
    border-radius: 12px;
    background: var(--fg);
    color: var(--bg);
    font: inherit;
    font-size: 0.9rem;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
    transition: background 0.2s, color 0.2s, transform 0.2s;
}
.fitbox__go:hover { background: var(--accent); color: #0a0c11; }
.fitbox__go:active { transform: translateY(1px); }
.fitbox__go:disabled { cursor: progress; background: var(--accent-soft); color: var(--fg); }
.fitbox__go:disabled::before {
    content: "";
    width: 0.8rem;
    height: 0.8rem;
    border: 2px solid var(--accent-line);
    border-top-color: var(--accent);
    border-radius: 50%;
    animation: fitbox-spin 0.8s linear infinite;
}
@keyframes fitbox-spin { to { transform: rotate(360deg); } }

.fitbox__error {
    margin-top: 0.6rem;
    font-size: 0.82rem;
    line-height: 1.45;
    color: var(--bad);
}
.fitbox--error .fitbox__form { border-color: color-mix(in srgb, var(--bad) 55%, transparent); }

.fitbox__result { margin-top: 0.8rem; }

/* While it reads: the steps, each lit in turn. */
.fitbox__steps {
    display: grid;
    gap: 0.45rem;
    margin: 0;
    padding: 0.2rem 0 0.1rem;
    list-style: none;
}
.fitbox__steps li {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    font-size: 0.84rem;
    color: var(--fg-3);
    transition: color 0.3s;
}
.fitbox__steps i {
    position: relative;
    flex: 0 0 auto;
    width: 1rem;
    height: 1rem;
    border: 1.5px solid var(--line-2);
    border-radius: 50%;
}
.fitbox__steps li.is-active { color: var(--fg); }
.fitbox__steps li.is-active i {
    border-color: var(--accent-soft);
    border-top-color: var(--accent);
    animation: fitbox-spin 0.8s linear infinite;
}
.fitbox__steps li.is-done { color: var(--fg-2); }
.fitbox__steps li.is-done i { border-color: var(--accent-2); background: var(--accent-2); }
.fitbox__steps li.is-done i::after {
    content: "";
    position: absolute;
    left: 0.3rem;
    top: 0.14rem;
    width: 0.22rem;
    height: 0.44rem;
    border: solid var(--bg);
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}

/* The result's two actions under the card. */
.fitbox__after {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem 1rem;
    margin-top: 0.7rem;
}
.fitbox__report {
    padding: 0.5rem 1rem;
    border: 0;
    border-radius: 999px;
    background: var(--fg);
    color: var(--bg);
    font: inherit;
    font-size: 0.84rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.2s, color 0.2s;
}
.fitbox__report:hover { background: var(--accent); color: #0a0c11; }
.fitbox__again {
    padding: 0.3rem 0;
    border: 0;
    background: none;
    font: inherit;
    font-size: 0.84rem;
    color: var(--fg-2);
    text-decoration: underline;
    text-decoration-color: var(--line-2);
    text-underline-offset: 3px;
    cursor: pointer;
}
.fitbox__again:hover { color: var(--fg); text-decoration-color: var(--accent-line); }

/* The fit panel and, under it, the short CV in its envelope share the
   fit cell (user, 2026-10-27: a short version for the readers who will not
   browse the whole site, impossible to miss, maybe a sheet that jiggles in
   an envelope as if asking to be opened; 2026-10-28: in the middle). */
.hero__actions {
    grid-area: fit;
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: clamp(0.75rem, 1.6vw, 1.25rem);
    min-width: 0;
}

/* The envelope: a sheet of the real CV in miniature keeps hopping out of
   it, lighting the envelope from inside each time it rises, and on a click
   grows into the sheet itself (cv.js). Centred under the fit panel, with
   one line and who it is for (user, 2026-10-28: only "Read the short CV"
   and under it "if you're in a hurry", no arrow, in the middle, the
   animation never stopping and easy to see). Its colours follow the theme;
   the paper is paper in both. Every size follows --env-w, the envelope's
   width (the drawing is 132 units wide). */
.brief {
    --env-w: 156px;
    --env-back: #121726;
    --env-flap: #1a2033;
    --env-front-a: #262e44;
    --env-front-b: #191f2f;
    --env-edge: rgba(255, 255, 255, 0.16);
    --env-fold: rgba(255, 255, 255, 0.09);
    --hop: 3.2s;
    position: relative;
    align-self: center;
    display: inline-flex;
    align-items: center;
    gap: 1.5rem;
    max-width: 100%;
    margin: 0;
    padding: 4.25rem 1rem 0.75rem; /* the sheet stands and hops in the top padding */
    border: 0;
    border-radius: var(--radius);
    background: none;
    color: var(--fg);
    font: inherit;
    text-align: left;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
:root[data-theme="light"] .brief {
    --env-back: #d9deea;
    --env-flap: #e6e9f2;
    --env-front-a: #ffffff;
    --env-front-b: #eef1f8;
    --env-edge: rgba(15, 18, 25, 0.14);
    --env-fold: rgba(15, 18, 25, 0.08);
}
.brief:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.brief.fade { opacity: 0; }
.brief.fade.in { opacity: 1; transition: opacity 0.7s ease; }

/* A pool of the page's own colour under it, as under the hero's text, so
   it reads over the curtain; and a halo of the accent behind the envelope
   that swells as the sheet rises. */
.brief::before,
.brief::after {
    content: "";
    position: absolute;
    z-index: -1;
    pointer-events: none;
}
.brief::before {
    inset: -1.25rem -3rem -1.5rem;
    background: radial-gradient(closest-side, color-mix(in srgb, var(--bg) 80%, transparent), color-mix(in srgb, var(--bg) 48%, transparent) 62%, transparent);
}
.brief::after {
    left: calc(1rem + var(--env-w) / 2 - 7rem);
    top: 1.25rem;
    width: 14rem;
    height: 10.5rem;
    background: radial-gradient(closest-side, color-mix(in srgb, var(--accent) 30%, transparent), transparent);
    opacity: 0.7;
    animation: brief-halo var(--hop) ease-in-out 1s infinite backwards;
}

.brief__env {
    position: relative;
    flex: none;
    width: var(--env-w);
    height: calc(var(--env-w) * 84 / 132);
    filter: drop-shadow(0 16px 18px rgba(0, 0, 0, 0.42));
    animation: brief-land var(--hop) ease-out 1s infinite backwards;
}
:root[data-theme="light"] .brief__env { filter: drop-shadow(0 14px 16px rgba(15, 18, 25, 0.16)); }
.brief__back {
    position: absolute;
    left: 0;
    top: calc(var(--env-w) * -30 / 132);
    width: 100%;
    height: calc(var(--env-w) * 114 / 132);
    overflow: visible;
}
.brief__flap { fill: var(--env-flap); stroke: var(--env-edge); stroke-width: 1; stroke-linejoin: round; }
.brief__panel { fill: var(--env-back); stroke: var(--env-edge); stroke-width: 1; }
/* The light inside: it brightens as the sheet rises, around the sheet and
   through the frosted pocket. */
.brief__glow {
    position: absolute;
    left: -22%;
    right: -22%;
    top: -78%;
    height: 150%;
    background: radial-gradient(closest-side, color-mix(in srgb, var(--accent-2) 92%, transparent), color-mix(in srgb, var(--accent) 58%, transparent) 48%, transparent);
    opacity: 0.55;
    transition: scale 0.45s ease;
    animation: brief-glow var(--hop) ease-in-out 1s infinite backwards;
}
/* The sheet's window: open above, closed at the envelope's bottom edge. */
.brief__slot {
    position: absolute;
    left: 0;
    right: 0;
    top: calc(var(--env-w) * -100 / 132);
    bottom: 3px;
    overflow: hidden;
    pointer-events: none;
}
.brief__paper {
    position: absolute;
    left: calc(var(--env-w) * 18 / 132);
    top: calc(var(--env-w) * 62 / 132); /* 38 units of it above the envelope */
    width: calc(var(--env-w) * 96 / 132);
    height: calc(var(--env-w) * 136 / 132);
    border-radius: 3px;
    background: #fbfbf9;
    box-shadow: 0 1px 0 rgba(0, 0, 0, 0.05), 0 8px 14px -8px rgba(0, 0, 0, 0.45);
    transform-origin: 50% 100%;
    transition: translate 0.45s cubic-bezier(0.3, 1.35, 0.5, 1);
    animation: brief-hop var(--hop) 1s infinite backwards;
}
.brief__paper svg { display: block; width: 100%; height: 100%; }
.brief__mini-name { font-family: var(--font-display); font-size: 8.4px; font-weight: 700; letter-spacing: -0.35px; fill: #141924; }
.brief__mini-role { font-family: var(--font-display); font-size: 4.7px; font-weight: 600; fill: url(#brief-ink); }
.brief__mini-meta rect, .brief__mini-date { fill: #c3c9d6; }
.brief__mini-rule { fill: #141924; }
.brief__mini-label rect { fill: #4457d6; }
.brief__mini-line rect { fill: #d5dae4; }
.brief__mini-dot rect { fill: #0d9f88; }
.brief__mini-job { fill: #4a5263; }
/* The pocket is frosted glass, like the hero's panels: the rest of the
   sheet and the light show through it, softly. */
.brief__front {
    position: absolute;
    inset: 0;
    border-radius: calc(var(--env-w) * 7 / 132);
    background: linear-gradient(180deg, color-mix(in srgb, var(--env-front-a) 70%, transparent), color-mix(in srgb, var(--env-front-b) 88%, transparent));
    -webkit-backdrop-filter: blur(4px) saturate(1.2);
    backdrop-filter: blur(4px) saturate(1.2);
    box-shadow: inset 0 0 0 1px var(--env-edge), inset 0 1px 0 rgba(255, 255, 255, 0.1);
}
.brief__front svg { display: block; width: 100%; height: 100%; }
.brief__fold { fill: none; stroke: var(--env-fold); stroke-width: 1; stroke-linecap: round; stroke-linejoin: round; }
/* His monogram, where the folds meet: the same mark as the top bar's. */
.brief__seal {
    position: absolute;
    left: calc(var(--env-w) * 54 / 132);
    top: calc(var(--env-w) * 33 / 132);
    display: grid;
    place-items: center;
    width: calc(var(--env-w) * 24 / 132);
    height: calc(var(--env-w) * 24 / 132);
    border-radius: 50%;
    background: linear-gradient(135deg, var(--accent), var(--accent-2));
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35), inset 0 0 0 1.5px rgba(255, 255, 255, 0.28);
    font-family: var(--font-mono);
    font-size: calc(var(--env-w) * 8 / 132);
    font-weight: 500;
    letter-spacing: 0.02em;
    line-height: 1;
    color: #0a0c11;
}

/* Pointed at, the sheet hops higher and the light grows. */
.brief:hover .brief__paper, .brief:focus-visible .brief__paper { translate: 0 -14px; }
.brief:hover .brief__glow, .brief:focus-visible .brief__glow { scale: 1.15; }

/* One hop, over and over: a small dip, up out of the envelope with a tilt,
   a moment in the air, down, a small bounce, a breath. The light, the halo
   and the envelope keep time with it (the same length and start; cv.js
   restarts them together after the sheet comes back). */
@keyframes brief-hop {
    0% { transform: none; animation-timing-function: ease-in-out; }
    8% { transform: translateY(2px) rotate(0.5deg); animation-timing-function: cubic-bezier(0.2, 0.75, 0.3, 1); }
    30% { transform: translateY(-22px) rotate(-2deg); animation-timing-function: ease-in-out; }
    40% { transform: translateY(-19px) rotate(-1deg); animation-timing-function: cubic-bezier(0.55, 0, 0.85, 0.4); }
    52% { transform: translateY(0) rotate(0.7deg); animation-timing-function: ease-out; }
    60% { transform: translateY(-5px) rotate(-0.3deg); animation-timing-function: ease-in; }
    68%, 100% { transform: none; }
}
@keyframes brief-glow {
    0%, 100% { opacity: 0.3; transform: scale(0.9); }
    32% { opacity: 1; transform: scale(1.04); }
    46% { opacity: 0.8; }
    64% { opacity: 0.4; transform: scale(0.94); }
}
@keyframes brief-halo {
    0%, 100% { opacity: 0.5; transform: scale(0.94); }
    34% { opacity: 1; transform: scale(1.06); }
}
@keyframes brief-land {
    0%, 51%, 100% { transform: none; }
    54% { transform: translateY(1.5px); }
    62% { transform: none; }
}

/* The text sits level with the middle of the envelope and the sheet above
   it together, not of the envelope alone. */
.brief__text { display: grid; gap: 0.4rem; min-width: 0; margin-top: calc(var(--env-w) * -38 / 132); }
.brief__title {
    position: relative;
    justify-self: start;
    padding-bottom: 0.45rem;
    font-family: var(--font-display);
    font-variation-settings: "opsz" 48;
    font-weight: 600;
    font-size: clamp(1.35rem, 2vw, 1.7rem);
    letter-spacing: -0.02em;
    line-height: 1.12;
    color: var(--fg);
}
/* A short line of the page's two accents under it, drawn out to its full
   width when pointed at. */
.brief__title::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 2px;
    border-radius: 2px;
    background: linear-gradient(90deg, var(--accent), var(--accent-2));
    transform: scaleX(0.35);
    transform-origin: 0 50%;
    transition: transform 0.5s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.brief:hover .brief__title::after, .brief:focus-visible .brief__title::after { transform: none; }
.brief__sub { font-size: 0.92rem; line-height: 1.4; color: var(--fg-2); }

/* Hero visual: the digital twin (his head passing through a curtain of
   light, drawn straight onto the page, no box, no background) and the chat
   under it, drawn as the head's speech bubble: no caption, the tail says
   who is talking. */

/* Frames where the head sits (avatar.js reads this rect); holds only the
   offline fallback. It stands on the chat: the bottom of the space beside
   the text, ending a little above the chat's row, so the chin stays over
   the bubble's tail wherever the text column puts the chat and clears the
   bubble even when he looks all the way down at it (user, 2026-09-24: his
   chin went into the chat). */
.twin__stage {
    grid-area: visual;
    align-self: end;
    position: relative;
    height: clamp(340px, 33vw, 440px);
    margin-bottom: calc(0.6rem - 1.25rem - 0.5rem); /* room for the chin, less the row gap and the chat's margin */
}
/* A short laptop screen: a little less head. */
@media (min-width: 861px) and (max-height: 820px) {
    .twin__stage { height: clamp(320px, 30vw, 400px); }
}

/* The curtain's canvas: the whole hero, edge to edge of the page, from the
   very top (under the floating topbar) to the marquee. The head stays
   framed to .twin__stage (avatar.js reads that rect on its own). It takes
   no clicks; the curtain is dimmed behind the text column, runs on behind
   the glass chat and fit panel, and melts into the page at the bottom. */
.twin__canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
    pointer-events: none;
}

.twin__fallback {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
}
.twin__fallback span {
    font-family: var(--font-display);
    font-variation-settings: "opsz" 96;
    font-weight: 700;
    font-size: clamp(5rem, 12vw, 8rem);
    letter-spacing: -0.06em;
    background: linear-gradient(135deg, var(--accent), var(--accent-2));
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    opacity: 0.6;
}

/* Chat: the speech bubble under the head. The tail is a rotated square
   with the same border, hanging off the top edge under the chin. Beside
   the fit panel it starts level with it, as small as what it holds, and
   grows down with the conversation up to --talk-max, then the log scrolls
   (chat.js eases the height; the grid row already holds the room, so the
   page never shifts while the head types). On a phone it has a fixed
   height, since the summary follows it. */
.talk {
    grid-area: talk;
    position: relative;
    display: flex;
    flex-direction: column;
    max-height: var(--talk-max, 22rem);
    margin-top: 0.5rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    /* Glass over the curtain, which runs on behind it. */
    background: linear-gradient(180deg, var(--card-hover), var(--card)), var(--glass);
    -webkit-backdrop-filter: blur(16px) saturate(1.3);
    backdrop-filter: blur(16px) saturate(1.3);
    transition: border-color 0.3s;
    scroll-margin-top: 6rem;
}
.talk--grow { transition: border-color 0.3s, height 0.26s cubic-bezier(0.25, 0.8, 0.3, 1); }

/* The bubble's header: who is talking. */
.talk__head {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.6rem 1.1rem 0.45rem 1.25rem;
    border-bottom: 1px solid var(--line);
    font-family: var(--font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--fg-3);
}
.talk__who {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--fg-2);
}
.talk__dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--accent-2);
    box-shadow: 0 0 8px var(--glow-2), 0 0 0 0 var(--accent-2);
    animation: talk-dot 2.4s ease-out infinite;
}
@keyframes talk-dot {
    0% { box-shadow: 0 0 8px var(--glow-2), 0 0 0 0 color-mix(in srgb, var(--accent-2) 55%, transparent); }
    70%, 100% { box-shadow: 0 0 8px var(--glow-2), 0 0 0 7px transparent; }
}
.twin__stage[data-state="offline"] ~ .talk .talk__dot { background: var(--fg-3); box-shadow: none; animation: none; }
.talk::before {
    content: "";
    position: absolute;
    top: -7px;
    left: 50%;
    width: 12px;
    height: 12px;
    margin-left: -6px;
    border-left: 1px solid var(--line);
    border-top: 1px solid var(--line);
    border-radius: 2px 0 0 0;
    background: linear-gradient(135deg, var(--card-hover), transparent 70%), var(--glass);
    -webkit-backdrop-filter: blur(16px) saturate(1.3);
    backdrop-filter: blur(16px) saturate(1.3);
    transform: rotate(45deg);
    transition: border-color 0.3s;
}
.talk:focus-within { border-color: var(--line-2); }
.talk:focus-within::before { border-color: var(--line-2); }

.talk__log {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
    overflow-y: auto;
    padding: 1.1rem 1.25rem 0.6rem;
    overscroll-behavior: contain;
    scrollbar-width: thin;
    scrollbar-color: var(--line-2) transparent;
    scrollbar-gutter: stable;
}
/* Still growing: everything fits, and a new line is revealed by the bubble
   easing down rather than by a scroll. Beside the fit panel only: on a phone
   the bubble has a fixed height and the log always scrolls. */
@media (min-width: 861px) {
    .talk--grow:not(.talk--full) .talk__log { overflow-y: hidden; }
}

.talk__msg {
    font-size: 0.94rem;
    line-height: 1.55;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.talk__msg--avatar {
    position: relative;
    padding-left: 1.15rem;
    color: var(--fg);
}
.talk__msg--avatar::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.6em;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--accent), var(--accent-2));
    box-shadow: 0 0 8px var(--glow);
}
/* A link the page itself has, or a project named in an answer (it lights
   the project's clips in the portfolio). */
.talk__msg a,
.talk__ref {
    padding: 0;
    border: 0;
    background: none;
    color: var(--accent);
    font: inherit;
    text-decoration: underline;
    text-decoration-color: var(--accent-line);
    text-decoration-thickness: 1px;
    text-underline-offset: 0.18em;
    cursor: pointer;
}
.talk__msg a:hover,
.talk__ref:hover { text-decoration-color: currentColor; }

/* The reader's own name or company, in the greeting only, typed straight
   into a quiet pill so a personalised link is noticed at a glance. */
.talk__mention {
    -webkit-box-decoration-break: clone;
    box-decoration-break: clone;
    padding: 0.05em 0.55em;
    border: 1px solid var(--accent-line);
    border-radius: 999px;
    background: var(--accent-soft);
    color: var(--accent-2);
    font-weight: 600;
}
.talk__msg--typing::after {
    content: "";
    display: inline-block;
    width: 2px;
    height: 1em;
    margin-left: 2px;
    vertical-align: -0.15em;
    background: var(--accent);
    animation: talk-caret 0.9s steps(2, start) infinite;
}
@keyframes talk-caret { to { visibility: hidden; } }

/* The answer is on its way: three dots where it will appear. */
.talk__dots {
    display: inline-flex;
    gap: 4px;
    height: 1.55em;
    align-items: center;
}
.talk__dots i {
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--fg-3);
    animation: talk-wait 1.2s ease-in-out infinite;
}
.talk__dots i:nth-child(2) { animation-delay: 0.15s; }
.talk__dots i:nth-child(3) { animation-delay: 0.3s; }
@keyframes talk-wait {
    0%, 60%, 100% { opacity: 0.3; transform: translateY(0); }
    30% { opacity: 1; transform: translateY(-2px); }
}

.talk__msg--user {
    align-self: flex-end;
    max-width: 88%;
    padding: 0.45rem 0.85rem;
    border: 1px solid var(--accent-line);
    border-radius: 14px 14px 4px 14px;
    background: var(--accent-soft);
    font-size: 0.9rem;
}

.talk__form {
    flex: 0 0 auto;
    display: flex;
    align-items: flex-end;
    gap: 0.5rem;
    padding: 0.55rem 0.7rem 0.6rem 0.8rem;
    border-top: 1px solid var(--line);
    transition: border-color 0.3s;
}
.talk__form:focus-within { border-top-color: var(--accent-line); }

/* One line that grows to four when a description is pasted (the bubble
   keeps its height: the log gives the room). */
.talk__input {
    flex: 1 1 auto;
    min-width: 0;
    max-height: 6.2rem;
    margin: 0;
    padding: 0.55rem 0;
    border: 0;
    background: transparent;
    color: var(--fg);
    font: inherit;
    font-size: 0.95rem;
    line-height: 1.45;
    resize: none;
    overflow-y: auto;
    scrollbar-width: thin;
    field-sizing: content;
}
.talk__input::placeholder { color: var(--fg-3); transition: opacity 0.25s; }
.talk__input.is-swapping::placeholder { opacity: 0; }
.talk__input:focus { outline: none; }

.talk__send {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 2.4rem;
    height: 2.4rem;
    padding: 0;
    border: 1px solid transparent;
    border-radius: 50%;
    background: var(--fg);
    color: var(--bg);
    cursor: pointer;
    transition: background 0.2s, color 0.2s, transform 0.2s;
}
.talk__send:hover { background: var(--accent); color: #0a0c11; }
.talk__send:active { transform: scale(0.94); }
/* While an answer is coming the button stops it. */
.talk__icon--stop { display: none; }
.talk--busy .talk__icon--send { display: none; }
.talk--busy .talk__icon--stop { display: block; }

/* The line in the contact card that points back up to the fit check. */
.cta__fit {
    display: inline-flex;
    align-items: flex-start;
    gap: 0.55rem;
    margin-top: 1.1rem;
    max-width: 40ch;
    font-size: 0.9rem;
    line-height: 1.45;
    color: var(--fg-2);
    text-decoration: none;
}
.cta__fit svg { flex: 0 0 auto; margin-top: 0.2rem; color: var(--accent); }
.cta__fit:hover { color: var(--fg); text-decoration: underline; text-decoration-color: var(--accent-line); }

/* The fit card in the chat: the score ring, the role, a bar of strong /
   partial / gap, and the door to the full report. The colours follow the
   verdict through --fit-color. */
.fit {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 0.35rem 0.9rem;
    align-items: center;
    padding: 0.75rem 0.85rem 0.75rem 0.85rem;
    border: 1px solid var(--line-2);
    border-radius: 14px;
    background: var(--card);
    white-space: normal;
    cursor: pointer; /* the whole card opens the report */
    transition: border-color 0.2s;
    --fit-color: var(--accent);
}
.fit:hover, .fit:focus-visible { border-color: var(--fit-color); outline: none; }
.fit::before { display: none; }
.fit[data-level="strong"], .fit[data-level="good"] { --fit-color: var(--ok); }
.fit[data-level="partial"] { --fit-color: var(--warn); }
.fit[data-level="weak"] { --fit-color: var(--bad); }

.fit__ring, .fitr__ring {
    position: relative;
    display: grid;
    place-items: center;
    width: 4.6rem;
    height: 4.6rem;
}
.fit__ring svg, .fitr__ring svg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    transform: rotate(-90deg);
}
.ring__track {
    fill: none;
    stroke: var(--line-2);
    stroke-width: 2;
    stroke-dasharray: 1 3.6;   /* a dotted track, like the head's nodes */
    stroke-linecap: round;
}
.ring__fill {
    fill: none;
    stroke: var(--fit-color);
    stroke-width: 4;
    stroke-linecap: round;
    transition: stroke-dashoffset 1.1s cubic-bezier(0.22, 0.61, 0.36, 1);
}
.ring__num {
    font-family: var(--font-display);
    font-size: 1.35rem;
    font-weight: 700;
    line-height: 1;
    letter-spacing: -0.02em;
    color: var(--fg);
}
.ring__of {
    position: absolute;
    bottom: 0.95rem;
    font-family: var(--font-mono);
    font-size: 0.5rem;
    color: var(--fg-3);
}

.fit__body { display: grid; gap: 0.3rem; min-width: 0; }
.fit__role {
    margin: 0;
    font-family: var(--font-display);
    font-size: 0.98rem;
    font-weight: 600;
    line-height: 1.25;
    color: var(--fg);
}
.fit__co { font-weight: 400; color: var(--fg-2); }
.fit__verdict { margin: 0; font-size: 0.82rem; line-height: 1.4; color: var(--fg-2); }
.fit__bar {
    display: flex;
    height: 5px;
    border-radius: 999px;
    overflow: hidden;
    background: var(--line);
}
.fit__bar span { display: block; height: 100%; transition: width 0.9s ease; }
.fit__bar-strong { background: var(--ok); }
.fit__bar-partial { background: var(--warn); }
.fit__bar-gap { background: var(--bad); }
.fit__counts, .fitr__counts {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    margin: 0;
    font-family: var(--font-mono);
    font-size: 0.68rem;
    color: var(--fg-3);
}
.pill {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.14rem 0.55rem;
    border-radius: 999px;
    font-family: var(--font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.01em;
    white-space: nowrap;
    color: var(--fg);
    background: var(--chip);
    border: 1px solid var(--line-2);
}
.pill::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.pill--strong { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 45%, transparent); }
.pill--partial { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 45%, transparent); }
.pill--gap { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 45%, transparent); }

/* The full report: a dialog over the page. */
.fitr {
    width: min(58rem, calc(100vw - 2rem));
    max-height: calc(100vh - 2rem);
    margin: auto;
    padding: 0;
    border: 1px solid var(--line-2);
    border-radius: var(--radius);
    background: var(--bg-2);
    color: var(--fg);
    box-shadow: var(--shadow);
    --fit-color: var(--accent);
}
.fitr[data-level="strong"], .fitr[data-level="good"] { --fit-color: var(--ok); }
.fitr[data-level="partial"] { --fit-color: var(--warn); }
.fitr[data-level="weak"] { --fit-color: var(--bad); }
.fitr::backdrop { background: rgba(5, 6, 10, 0.72); backdrop-filter: blur(6px); }
body:has(.fitr[open]) { overflow: hidden; }
.fitr__card { padding: 1.5rem 1.75rem 1.5rem; }

.fitr__head {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    gap: 1.25rem;
    align-items: center;
    padding-bottom: 1.25rem;
    border-bottom: 1px solid var(--line);
}
.fitr__ring { width: 6.4rem; height: 6.4rem; }
.fitr__ring .ring__num { font-size: 1.9rem; }
.fitr__ring .ring__of { bottom: 1.35rem; font-size: 0.6rem; }
.fitr__lead { display: grid; gap: 0.35rem; min-width: 0; }
.fitr__kicker {
    margin: 0;
    font-family: var(--font-mono);
    font-size: 0.7rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--fg-3);
}
.fitr__title {
    margin: 0;
    font-family: var(--font-display);
    font-size: clamp(1.25rem, 2.4vw, 1.6rem);
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -0.02em;
}
.fitr__title span { font-weight: 400; color: var(--fg-2); }
.fitr__verdict { margin: 0; font-size: 0.98rem; line-height: 1.45; color: var(--fg-2); }
.fitr__close {
    align-self: start;
    display: grid;
    place-items: center;
    width: 2.4rem;
    height: 2.4rem;
    padding: 0;
    border: 1px solid var(--line-2);
    border-radius: 50%;
    background: transparent;
    color: var(--fg-2);
    cursor: pointer;
}
.fitr__close:hover { border-color: var(--fg); color: var(--fg); }

.fitr__section { padding: 1.25rem 0 0; }
.fitr__h {
    margin: 0 0 0.6rem;
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--fg-3);
}
.fitr__list { margin: 0; padding-left: 1.2rem; display: grid; gap: 0.4rem; font-size: 0.95rem; line-height: 1.5; color: var(--fg-2); }
.fitr__list strong { color: var(--fg); font-weight: 600; }
.fitr__list--plus, .fitr__list--gaps { list-style: none; padding-left: 0; }
.fitr__list--plus li, .fitr__list--gaps li { position: relative; padding-left: 1.4rem; }
.fitr__list--plus li::before, .fitr__list--gaps li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.55em;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--ok);
    box-shadow: 0 0 8px color-mix(in srgb, var(--ok) 60%, transparent);
}
.fitr__list--gaps li::before { background: var(--bad); box-shadow: 0 0 8px color-mix(in srgb, var(--bad) 60%, transparent); }
.fitr__none { margin: 0; font-size: 0.95rem; color: var(--fg-2); }

.fitr__tabs { display: inline-flex; gap: 0.25rem; margin-bottom: 0.75rem; padding: 0.2rem; border: 1px solid var(--line); border-radius: 999px; }
.fitr__tabs [role="tab"] {
    padding: 0.32rem 0.85rem;
    border: 0;
    border-radius: 999px;
    background: transparent;
    font-family: var(--font-mono);
    font-size: 0.72rem;
    color: var(--fg-2);
    cursor: pointer;
}
.fitr__tabs [role="tab"][aria-selected="true"] { background: var(--accent-soft); color: var(--fg); }

.fitr__scroll { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius-sm); }
.fitr__table { width: 100%; min-width: 34rem; border-collapse: collapse; font-size: 0.9rem; line-height: 1.45; }
.fitr__table th, .fitr__table td { padding: 0.65rem 0.8rem; vertical-align: top; text-align: left; border-bottom: 1px solid var(--line); }
.fitr__table th {
    font-family: var(--font-mono);
    font-size: 0.68rem;
    font-weight: 500;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--fg-3);
    background: var(--bg-3);
}
.fitr__table tbody tr:last-child td { border-bottom: 0; }
.fitr__table tbody tr:hover td { background: var(--card-hover); }
.fitr__n { width: 2rem; font-family: var(--font-mono); font-size: 0.72rem; color: var(--fg-3); }
.fitr__req { width: 32%; font-weight: 500; color: var(--fg); }
.fitr__must {
    margin-left: 0.35rem;
    padding: 0.05rem 0.4rem;
    border-radius: 999px;
    background: var(--accent-soft);
    font-family: var(--font-mono);
    font-size: 0.62rem;
    font-style: normal;
    letter-spacing: 0.04em;
    color: var(--accent);
    vertical-align: middle;
}
.fitr__ev { color: var(--fg-2); }
.fitr__st { width: 6rem; white-space: nowrap; }

.fitr__md {
    max-height: 24rem;
    margin: 0;
    padding: 1rem 1.1rem;
    overflow: auto;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--bg-3);
    font-family: var(--font-mono);
    font-size: 0.76rem;
    line-height: 1.55;
    color: var(--fg-2);
    white-space: pre;
}

.fitr__foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.9rem 1.5rem;
    margin-top: 1.5rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--line);
}
.fitr__note { flex: 1 1 22rem; margin: 0; font-size: 0.8rem; line-height: 1.5; color: var(--fg-3); }
.fitr__actions { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.fitr__actions .btn { padding: 0.6rem 1.05rem; font-size: 0.86rem; cursor: pointer; }

.sr-only {
    -webkit-user-select: none;
    user-select: none;
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Keyword strip ---------------------------------------------------------- */

.marquee {
    position: relative;
    z-index: 1;
    overflow: hidden;
    border-block: 1px solid var(--line);
    padding-block: 0.95rem;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}

.marquee__track {
    display: flex;
    width: max-content;
    animation: marquee 70s linear infinite;
}
.marquee:hover .marquee__track { animation-play-state: paused; }

.marquee ul {
    display: flex;
    gap: 2.4rem;
    padding-right: 2.4rem;
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--fg-3);
    white-space: nowrap;
}
.marquee li { display: inline-flex; align-items: center; gap: 0.9rem; }
.marquee li::before {
    content: "";
    width: 5px;
    height: 5px;
    border-radius: 1px;
    transform: rotate(45deg);
    background: var(--accent);
    opacity: 0.8;
}

@keyframes marquee { to { transform: translateX(-50%); } }

/* Sections --------------------------------------------------------------- */


.sec {
    padding-block: clamp(2.75rem, 5.5vw, 4.75rem);
    scroll-margin-top: 5rem;
}

.sec__head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
    gap: 1.25rem 1.5rem;
    padding-bottom: 1.25rem;
    margin-bottom: clamp(1.5rem, 3vw, 2.25rem);
    border-bottom: 1px solid var(--line);
}

.sec__title {
    font-family: var(--font-display);
    font-variation-settings: "opsz" 72;
    font-weight: 600;
    font-size: clamp(2rem, 4vw, 3rem);
    line-height: 1;
    letter-spacing: -0.035em;
}

.sec__intro {
    max-width: 34ch;
    font-size: 0.92rem;
    line-height: 1.5;
    text-align: right;
    color: var(--fg-3);
}

/* Skills (vertical stack) ------------------------------------------------ */

.stack {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.skill {
    display: grid;
    grid-template-columns: 16rem minmax(0, 1fr);
    gap: 1.5rem 2rem;
    padding: 1.35rem 1.6rem 1.45rem;
}

.skill__side {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    align-self: start;
}

.skill__name {
    font-family: var(--font-display);
    font-variation-settings: "opsz" 48;
    font-weight: 600;
    font-size: 1.15rem;
    line-height: 1.2;
    letter-spacing: -0.02em;
}

.skill--primary { padding-block: 1.6rem 1.7rem; }
.skill--primary .skill__name { font-size: 1.45rem; }

.skill__sub {
    margin: 0 0 0.5rem;
    font-family: var(--font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--accent);
}
.skill__sub + .tags { margin-bottom: 1.15rem; }
.skill__sub + .tags:last-child { margin-bottom: 0; }
.skill__body > :first-child { margin-top: 0; }

.skill__desc {
    margin-top: 1rem;
    max-width: 66ch;
    font-size: 0.94rem;
    color: var(--fg-2);
}

.skill__list {
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}
.skill__list li {
    position: relative;
    padding-left: 1.15rem;
    font-size: 0.93rem;
    color: var(--fg-2);
}
.skill__list li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.62em;
    width: 5px;
    height: 5px;
    border-radius: 1px;
    transform: rotate(45deg);
    background: var(--accent);
}

/* Spec rows (technical & personal) --------------------------------------- */

.spec { padding: 0.35rem 1.5rem; }

.spec__row {
    display: grid;
    grid-template-columns: 12rem minmax(0, 1fr);
    gap: 1.5rem;
    padding-block: 1.1rem;
    border-bottom: 1px solid var(--line);
}
.spec__row:last-child { border-bottom: 0; }

.spec dt {
    padding-top: 0.2rem;
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--fg-3);
}

.spec dd {
    font-size: 0.97rem;
    color: var(--fg-2);
    max-width: 80ch;
}

.langs {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    max-width: 26rem;
}
.langs li {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    padding-bottom: 0.4rem;
    border-bottom: 1px dashed var(--line);
}
.langs li:last-child { border-bottom: 0; padding-bottom: 0; }
.langs__lvl { font-family: var(--font-mono); font-size: 0.78rem; color: var(--fg-3); }

.hobbies { margin-top: 1rem; padding: 1.5rem; }
.hobbies__title {
    font-family: var(--font-display);
    font-variation-settings: "opsz" 48;
    font-weight: 600;
    font-size: 1.15rem;
    letter-spacing: -0.02em;
    margin-bottom: 0.6rem;
}
.hobbies p { max-width: 80ch; color: var(--fg-2); }

/* Timeline / jobs -------------------------------------------------------- */

.timeline {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 1.1rem;
    padding-left: 2.25rem;
}
.timeline::before {
    content: "";
    position: absolute;
    left: 0.45rem;
    top: 1.4rem;
    bottom: 1.4rem;
    width: 1px;
    background: linear-gradient(var(--accent-line), var(--line));
}

.job { position: relative; }
.job::before {
    content: "";
    position: absolute;
    left: calc(-2.25rem + 0.45rem - 4.5px);
    top: 1.55rem;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--bg);
    border: 1px solid var(--line-2);
    z-index: 2;
}
.job--current::before {
    background: var(--accent);
    border-color: var(--accent);
    box-shadow: 0 0 0 5px var(--accent-soft), 0 0 22px var(--glow);
}

.job__card { padding: 1.5rem 1.6rem 1.6rem; }

.job__head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1rem 2rem;
    flex-wrap: wrap;
}

.job__title {
    font-family: var(--font-display);
    font-variation-settings: "opsz" 48;
    font-weight: 600;
    font-size: 1.4rem;
    line-height: 1.15;
    letter-spacing: -0.025em;
}
.job__type { font-weight: 400; color: var(--fg-3); }

.job__org { margin-top: 0.3rem; font-size: 0.95rem; color: var(--fg-2); }
.job__loc { color: var(--fg-3); }

.job__meta {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.35rem;
    flex: 0 0 auto;
}

.job__dates {
    font-family: var(--font-mono);
    font-size: 0.76rem;
    letter-spacing: 0.04em;
    color: var(--fg-2);
    white-space: nowrap;
}

.job__badge {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.2rem 0.6rem;
    border-radius: 999px;
    background: var(--accent-soft);
    border: 1px solid var(--accent-line);
    font-family: var(--font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--accent);
}
.job__badge::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent-2);
}

.job__list {
    margin-top: 1.2rem;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    max-width: 82ch;
}
.job__list li {
    position: relative;
    padding-left: 1.2rem;
    font-size: 0.95rem;
    color: var(--fg-2);
}
.job__list li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.68em;
    width: 5px;
    height: 5px;
    border-radius: 1px;
    transform: rotate(45deg);
    background: var(--accent);
}

.job__note {
    margin-top: 1rem;
    max-width: 82ch;
    font-size: 0.9rem;
    color: var(--fg-3);
}
.job__note-label {
    display: inline-block;
    margin-right: 0.5rem;
    font-family: var(--font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--accent);
}

.job__card > .tags { margin-top: 1.25rem; }

/* Education -------------------------------------------------------------- */

.edu {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem;
}

.edu__item { padding: 1.4rem 1.5rem 1.5rem; }

.edu__year {
    display: inline-block;
    margin-bottom: 0.9rem;
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.1em;
    color: var(--accent);
}

.edu__title {
    font-family: var(--font-display);
    font-variation-settings: "opsz" 48;
    font-weight: 600;
    font-size: 1.2rem;
    line-height: 1.2;
    letter-spacing: -0.02em;
}

.edu__org { margin-top: 0.3rem; font-size: 0.93rem; color: var(--fg-2); }
.edu__desc { margin-top: 0.55rem; font-size: 0.9rem; color: var(--fg-3); max-width: 60ch; }

/* Contact ---------------------------------------------------------------- */

.cta {
    display: grid;
    grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
    gap: 2rem 3rem;
    align-items: center;
    padding: clamp(1.75rem, 4vw, 2.75rem);
    border: 1px solid transparent;
    border-radius: var(--radius);
    background:
        linear-gradient(var(--bg-2), var(--bg-2)) padding-box,
        linear-gradient(120deg, var(--accent), var(--accent-2)) border-box;
    box-shadow: var(--shadow);
}

.cta__eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: 0.9rem;
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--fg-3);
}

.cta__title {
    font-family: var(--font-display);
    font-variation-settings: "opsz" 72;
    font-weight: 600;
    font-size: clamp(1.6rem, 3vw, 2.3rem);
    line-height: 1.1;
    letter-spacing: -0.03em;
    max-width: 18ch;
}

.cta__facts {
    display: grid;
    gap: 0.75rem;
}
.cta__facts > div {
    display: grid;
    grid-template-columns: 7rem minmax(0, 1fr);
    gap: 1rem;
    padding-bottom: 0.75rem;
    border-bottom: 1px solid var(--line);
}
.cta__facts > div:last-child { border-bottom: 0; padding-bottom: 0; }
.cta__facts dt {
    font-family: var(--font-mono);
    font-size: 0.7rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--fg-3);
    padding-top: 0.2rem;
}
.cta__facts dd { color: var(--fg); overflow-wrap: anywhere; }
.cta__facts a { text-decoration-color: var(--line-2); }
.cta__facts a:hover { color: var(--accent); text-decoration-color: currentColor; }

/* Portfolio -------------------------------------------------------------- */

/* Chapters (Unity games, Unity apps & tools, web/mobile/backend, AI; each
   site has them in its own order), then the projects: a lead is a whole row
   (the media and the text side by side, sides alternating), a half is a card
   (a phone beside its text, or a landscape clip above it), a tile is a small
   project in the packed grid under them, a system card is a project with no
   clip, told by how it works. */
.chapter {
    margin-top: clamp(3rem, 7vw, 5.5rem);
    scroll-margin-top: 5rem;
}
.sec__head + .chapter { margin-top: 0; }

.chapter__head {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    gap: 0.2rem 1rem;
    margin-bottom: clamp(1.5rem, 3vw, 2.25rem);
}
.chapter__icon {
    grid-row: span 2;
    display: grid;
    place-items: center;
    width: 3rem;
    height: 3rem;
    border: 1px solid var(--accent-line);
    border-radius: 14px;
    background: var(--accent-soft);
    color: var(--accent);
}
.chapter__icon svg { width: 1.45rem; height: 1.45rem; }
.chapter__title {
    font-family: var(--font-display);
    font-variation-settings: "opsz" 72;
    font-weight: 600;
    font-size: clamp(1.45rem, 2.6vw, 1.95rem);
    line-height: 1.1;
    letter-spacing: -0.03em;
}
.chapter__intro { font-size: 0.95rem; line-height: 1.5; color: var(--fg-3); }

/* Two cards side by side are as tall as each other. */
.works {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: clamp(1.25rem, 2.6vw, 2rem);
    align-items: stretch;
}
.work { position: relative; min-width: 0; scroll-margin-top: 6rem; }
.work--lead,
.work--wide { grid-column: 1 / -1; }

/* A lead: the media and the text side by side. */
.work--lead {
    display: grid;
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
    gap: clamp(1.5rem, 4vw, 3.5rem);
    align-items: center;
    padding-block: clamp(0.75rem, 2.5vw, 2rem);
}
.work--lead.work--flip { grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr); }
.work--lead.work--flip .work__media { order: 2; }

/* A half and a system card: cards like the rest of the page. */
.work--half,
.work--system {
    padding: clamp(1.1rem, 2.2vw, 1.5rem);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--card);
    transition: border-color 0.3s, background 0.3s;
}
.work--half:hover,
.work--system:hover { border-color: var(--line-2); background: var(--card-hover); }
.work--half {
    display: grid;
    grid-template-columns: minmax(0, 0.8fr) minmax(0, 1fr);
    gap: 1.25rem 1.5rem;
    align-items: center;
}
/* A landscape clip in a half: above the text. */
.work--half.work--top { grid-template-columns: minmax(0, 1fr); align-items: start; align-content: start; }

/* A project the chat has just named: a ring of light, once. */
.work.is-called { animation: work-called 2.4s ease-out; }
@keyframes work-called {
    0% { box-shadow: 0 0 0 0 var(--accent-line); }
    30% { box-shadow: 0 0 0 6px var(--accent-soft), 0 0 40px -6px var(--accent); }
    100% { box-shadow: 0 0 0 0 transparent; }
}
.work--lead.is-called { border-radius: var(--radius); }

/* The media: a device holding the clips, the strip of clips under it, the
   clip's caption; behind it a glow in the project's own colour. */
.work__media {
    position: relative;
    display: grid;
    justify-items: center;
    gap: 0.7rem;
    min-width: 0;
}
.work__glow {
    position: absolute;
    inset: 6% 2%;
    z-index: -1;
    border-radius: 50%;
    background: radial-gradient(closest-side, rgb(var(--glow-rgb, 141 162 255) / 0.75), transparent);
    filter: blur(48px);
    opacity: 0.5;
    pointer-events: none;
    transition: background 0.6s ease;
}
:root[data-theme="light"] .work__glow { opacity: 0.35; }

.device {
    position: relative;
    display: block;
    width: 100%;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.device__body {
    position: relative;
    display: block;
    width: min(100%, calc(var(--max-h, 560px) * var(--r, 1.6) + var(--bezel, 0px) * 2));
    margin-inline: auto;
    background: var(--device);
    transition: transform 0.5s cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 0.5s ease;
}
.device:hover .device__body,
.device:focus-visible .device__body { transform: translateY(-4px); }
.device:focus-visible { outline: none; }
.device:focus-visible .device__body { box-shadow: 0 0 0 3px var(--accent-line), var(--device-shadow); }
.device__screen {
    position: relative;
    display: block;
    overflow: hidden;
    aspect-ratio: var(--r, 1.6);
    background: #05060a;
    isolation: isolate;
}
.device__screen > img,
.device__screen > video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.device__screen > .is-contain { object-fit: contain; }
.device__ambient { filter: blur(22px) saturate(1.25) brightness(0.75); transform: scale(1.25); }
.device__video { opacity: 0; transition: opacity 0.45s ease; }
.device__video.is-on { opacity: 1; }

/* A phone: a dark bezel, the island on top. */
.device--phone .device__body {
    --bezel: 7px;
    padding: var(--bezel);
    border-radius: 34px;
    box-shadow: var(--device-shadow);
}
.device--phone .device__screen { border-radius: 27px; }
.device--phone .device__screen::after {
    content: "";
    position: absolute;
    top: 9px;
    left: 50%;
    z-index: 3;
    width: 26%;
    height: 15px;
    border-radius: 999px;
    background: #000;
    transform: translateX(-50%);
    pointer-events: none;
}
/* A window and a browser: a title bar with three lights (and the page's
   address, when it is a public one). */
.device--window .device__body,
.device--browser .device__body {
    border-radius: 14px;
    overflow: hidden;
    box-shadow: var(--device-shadow);
}
.device__bar {
    display: flex;
    align-items: center;
    gap: 6px;
    height: 28px;
    padding: 0 12px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
    background: #12141b;
}
.device__bar i {
    flex: none;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: #ff5f57;
}
.device__bar i:nth-child(2) { background: #febc2e; }
.device__bar i:nth-child(3) { background: #28c840; }
.device__url {
    display: block;
    min-width: 0;
    margin-inline: auto;
    padding: 2px 14px;
    border-radius: 6px;
    background: rgba(255, 255, 255, 0.06);
    font-family: var(--font-mono);
    font-size: 0.66rem;
    line-height: 1.4;
    color: #9aa3b5;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.device__bar:has(.device__url)::after { content: ""; width: 39px; flex: none; }
/* A screen (a squarish recording): a thin bezel. */
.device--screen .device__body {
    --bezel: 7px;
    padding: var(--bezel);
    border-radius: 22px;
    box-shadow: var(--device-shadow);
}
.device--screen .device__screen { border-radius: 15px; }
/* A VR view: a visor with a cut for the nose. */
.device--vr .device__body {
    --bezel: 9px;
    padding: var(--bezel);
    border-radius: 30px;
    box-shadow: var(--device-shadow);
    -webkit-mask: radial-gradient(15% 17% at 50% 103%, transparent 97%, #000 100%);
    mask: radial-gradient(15% 17% at 50% 103%, transparent 97%, #000 100%);
}
.device--vr .device__screen { border-radius: 22px; }
.device__badge {
    position: absolute;
    top: 16px;
    left: 18px;
    z-index: 4;
    padding: 3px 7px;
    border-radius: 6px;
    background: rgba(5, 6, 10, 0.6);
    font-family: var(--font-mono);
    font-size: 0.62rem;
    letter-spacing: 0.1em;
    color: #eef0f6;
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
}
/* The phone that goes with a web product, over the corner of its browser. */
.work__media--pair { padding: 0 9% 9% 0; justify-items: stretch; }
.device--mini {
    position: absolute;
    right: 0;
    bottom: 0;
    z-index: 2;
    width: 24%;
}
.device--mini .device__body { --bezel: 4px; border-radius: 22px; }
.device--mini .device__screen { border-radius: 18px; }
.device--mini .device__screen::after { top: 5px; height: 9px; }

/* One segment per clip on top of the screen, filling as the clip plays. */
.device__segs {
    position: absolute;
    top: 10px;
    left: 12px;
    right: 12px;
    z-index: 4;
    display: flex;
    gap: 4px;
    pointer-events: none;
}
.device--phone .device__segs { top: 30px; left: 16px; right: 16px; }
.device__segs i {
    position: relative;
    flex: 1;
    height: 3px;
    overflow: hidden;
    border-radius: 3px;
    background: rgba(255, 255, 255, 0.3);
    box-shadow: 0 0 6px rgba(0, 0, 0, 0.35);
}
.device__segs i::after {
    content: "";
    position: absolute;
    inset: 0;
    background: #fff;
    transform: scaleX(var(--p, 0));
    transform-origin: left;
}
.device__segs i.is-done::after { transform: none; }

/* A corner mark on the screen: a click opens the clip in full. Under the
   pointer, and always there on a touch screen. */
.device__hint {
    position: absolute;
    right: 10px;
    bottom: 10px;
    z-index: 4;
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    border: 1px solid rgba(255, 255, 255, 0.22);
    border-radius: 50%;
    background: rgba(8, 10, 15, 0.55);
    color: #eef0f6;
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    opacity: 0;
    transform: scale(0.8);
    transition: opacity 0.25s ease, transform 0.25s ease;
    pointer-events: none;
}
.device__hint svg { width: 13px; height: 13px; }
.device:hover .device__hint,
.device:focus-visible .device__hint { opacity: 1; transform: none; }
@media (hover: none) {
    .device__hint { opacity: 0.85; transform: none; }
}
.device--mini .device__hint { display: none; }

/* The clips of a project, as a strip under its device. */
.work__rail {
    display: flex;
    gap: 6px;
    max-width: 100%;
    padding: 3px;
    overflow-x: auto;
    scrollbar-width: none;
}
.work__rail::-webkit-scrollbar { display: none; }
/* Centred while it fits, scrollable from its first clip when it does not. */
.work__rail > :first-child { margin-left: auto; }
.work__rail > :last-child { margin-right: auto; }
.work__thumb {
    flex: none;
    height: 44px;
    aspect-ratio: var(--r, 1);
    padding: 0;
    overflow: hidden;
    border: 0;
    border-radius: 7px;
    background: #05060a;
    opacity: 0.5;
    cursor: pointer;
    transition: opacity 0.2s ease, box-shadow 0.2s ease;
}
.work__thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
.work__thumb:hover,
.work__thumb:focus-visible { opacity: 0.9; outline: none; }
.work__thumb:focus-visible { box-shadow: 0 0 0 2px var(--line-2); }
.work__thumb[aria-current="true"] { opacity: 1; box-shadow: 0 0 0 2px var(--accent); }
.work__caption {
    max-width: 46ch;
    min-height: 1.4em;
    font-size: 0.82rem;
    line-height: 1.4;
    text-align: center;
    text-wrap: balance;
    color: var(--fg-3);
}

/* The clips as written in the page: what shows without JavaScript. */
.work__clips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1rem;
    margin-bottom: 1rem;
    font-size: 0.82rem;
    color: var(--fg-3);
}
.work__clips li::before { content: "\25B6\FE0E"; margin-right: 0.4rem; font-size: 0.6rem; color: var(--accent); }

/* The text. */
.work__body { min-width: 0; }
.work__kicker {
    font-family: var(--font-mono);
    font-size: 0.7rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    line-height: 1.5;
    text-transform: uppercase;
    text-wrap: balance;
    color: var(--accent-2);
}
.work__name {
    margin-top: 0.3rem;
    font-family: var(--font-display);
    font-variation-settings: "opsz" 72;
    font-weight: 600;
    font-size: clamp(1.65rem, 2.9vw, 2.4rem);
    line-height: 1.05;
    letter-spacing: -0.035em;
}
.work--half .work__name,
.work--system .work__name { font-size: clamp(1.35rem, 2.1vw, 1.75rem); }
.work__line {
    margin-top: 0.7rem;
    max-width: 62ch;
    font-size: 1rem;
    line-height: 1.6;
    text-wrap: pretty;
    color: var(--fg-2);
}
.work--half .work__line,
.work--system .work__line { font-size: 0.94rem; }
.work__stack { margin-top: 1rem; }
.work__stack li { font-size: 0.7rem; padding: 0.26rem 0.6rem; }
.work__links { margin-top: 0.9rem; font-size: 0.9rem; }
.work__links a { color: var(--accent); }
.work__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 1.1rem;
}

/* A project with no clip: an icon, and how it works as a flow of steps, a
   light running through them. */
.work__icon {
    display: grid;
    place-items: center;
    width: 2.6rem;
    height: 2.6rem;
    margin-bottom: 1rem;
    border-radius: 12px;
    background: var(--accent-soft);
    color: var(--accent);
}
.work__icon svg { width: 1.3rem; height: 1.3rem; }
.work__flow {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.9rem;
    margin-top: 1rem;
}
.work__flow li {
    position: relative;
    padding: 0.36rem 0.62rem;
    border: 1px solid var(--line-2);
    border-radius: 8px;
    background: var(--bg-3);
    font-family: var(--font-mono);
    font-size: 0.7rem;
    line-height: 1.35;
    color: var(--fg);
    animation: flow-step 6s ease-in-out infinite;
    animation-delay: calc(var(--i, 0) * 0.5s);
}
.work__flow li:not(:last-child):not(.is-row-end)::after {
    content: "";
    position: absolute;
    top: 50%;
    right: calc(-0.9rem + 3px);
    width: calc(0.9rem - 6px);
    height: 1px;
    background: var(--accent-line);
}
@keyframes flow-step {
    0%, 14%, 100% { border-color: var(--line-2); box-shadow: none; }
    6% { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft), 0 0 16px -4px var(--accent); }
}

/* A system drawn by its layers: the clients, the backend, the data and the edge. */
.arch {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1.6rem;
    margin-top: 1.1rem;
}
.arch__col { position: relative; display: flex; flex-direction: column; gap: 0.4rem; }
.arch__col::before {
    content: attr(data-label);
    margin-bottom: 0.15rem;
    font-family: var(--font-mono);
    font-size: 0.62rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--fg-3);
}
.arch__col + .arch__col::after {
    content: "";
    position: absolute;
    top: 50%;
    left: -1.35rem;
    width: 1.1rem;
    height: 1px;
    background: var(--accent-line);
    box-shadow: 0 0 8px var(--accent);
}
.arch__col li {
    padding: 0.42rem 0.65rem;
    border: 1px solid var(--line-2);
    border-radius: 8px;
    background: var(--bg-3);
    font-family: var(--font-mono);
    font-size: 0.7rem;
    line-height: 1.35;
    color: var(--fg);
    animation: flow-step 6s ease-in-out infinite;
    animation-delay: calc(var(--i, 0) * 0.5s);
}
.work--wide.work--system {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    gap: 1rem clamp(1.5rem, 4vw, 3rem);
    align-items: start;
}
.work--wide .work__icon { grid-column: 1 / -1; margin-bottom: 0; }

/* In a wide card the steps run down the second column, boxes of one width
   joined by a line, like a diagram. */
.work__flow--column {
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: stretch;
    align-self: center;
    justify-self: center;
    width: min(100%, 21rem);
    gap: 0.8rem;
    margin-top: 0;
}
.work__flow--column li { padding-block: 0.5rem; text-align: center; }
.work__flow--column li:not(:last-child):not(.is-row-end)::after {
    top: calc(100% + 1px);
    left: 50%;
    right: auto;
    width: 1px;
    height: calc(0.8rem - 2px);
}

/* A Unity package: how it is added, its git address in a field with a copy
   button. */
.work__install {
    margin-top: 1.1rem;
    font-size: 0.84rem;
    line-height: 1.5;
    color: var(--fg-3);
}
.work__url {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.45rem;
    padding: 0.28rem 0.28rem 0.28rem 0.75rem;
    border: 1px solid var(--line-2);
    border-radius: 10px;
    background: var(--bg-3);
}
.work__url-text {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    font-family: var(--font-mono);
    font-size: 0.7rem;
    color: var(--fg-2);
    white-space: nowrap;
    text-overflow: ellipsis;
    -webkit-user-select: all;
    user-select: all;
}
.work__copy {
    flex: none;
    min-width: 4.6rem;
    padding: 0.32rem 0.75rem;
    border: 1px solid var(--line-2);
    border-radius: 7px;
    background: var(--card);
    color: var(--fg);
    font-family: var(--font-mono);
    font-size: 0.7rem;
    cursor: pointer;
    transition: border-color 0.2s, background 0.2s;
}
.work__copy:hover,
.work__copy:focus-visible { border-color: var(--accent-line); background: var(--accent-soft); outline: none; }

/* The smaller projects: a packed grid under the chapter, in reading order
   (script.js gives each tile its height in rows). */
.works__more {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    margin: clamp(2rem, 4.5vw, 3rem) 0 1.25rem;
    font-family: var(--font-mono);
    font-size: 0.7rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--fg-3);
}
.works__more::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.works--tiles {
    align-items: start;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 14.5rem), 1fr));
    gap: 1.5rem clamp(1rem, 2vw, 1.5rem);
}
.works--tiles.is-packed { grid-auto-rows: 4px; row-gap: 0; }
.work--tile .work__media { margin-bottom: 0.85rem; }
.work--tile .work__name { font-size: 1.25rem; }
.work--tile .work__line { margin-top: 0.4rem; font-size: 0.88rem; line-height: 1.5; }
.work--tile .work__actions { margin-top: 0.7rem; }

/* Buttons and links of a project, under its text and in the viewer. */
.proj-btns {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-top: 0.85rem;
}
.proj-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.34rem 0.75rem;
    border: 1px solid var(--line-2);
    border-radius: 999px;
    background: transparent;
    color: var(--fg);
    font-size: 0.78rem;
    line-height: 1.3;
    text-decoration: none;
    cursor: pointer;
    transition: border-color 0.2s, background 0.2s, color 0.2s;
}
a.proj-btn::after { content: "\2197"; font-size: 0.72rem; color: var(--fg-3); }
.proj-btn:hover,
.proj-btn:focus-visible { border-color: var(--accent-line); background: var(--accent-soft); outline: none; }
.proj-btn--ask::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent-2);
    box-shadow: 0 0 8px var(--accent-2);
}

/* The viewer (always dark): the clip as large as the stage holds it, with
   sound, the project's clips under it, everything about the project beside
   it. */
html.viewer-open { overflow: hidden; }
.viewer {
    width: 100vw;
    height: 100vh;
    height: 100dvh;
    max-width: none;
    max-height: none;
    margin: 0;
    padding: clamp(0.75rem, 2.5vw, 2rem);
    border: 0;
    background: rgba(5, 6, 10, 0.94);
    color: #eef0f6;
    overscroll-behavior: contain;
}
.viewer[open] {
    display: grid;
    place-items: center;
}
.viewer::backdrop { background: transparent; }
.viewer__panel {
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 1fr) 19rem;
    gap: 1.5rem;
    width: min(100%, 1400px);
    height: min(100%, 900px);
    padding: 1rem;
    border: 1px solid transparent;
    border-radius: 16px;
    background:
        linear-gradient(#0c0e14, #0c0e14) padding-box,
        linear-gradient(155deg, #6b7388, #10131a 25%, #2a303d 50%, #10131a 75%, #6b7388) border-box;
    box-shadow: 0 50px 120px -40px #000, 0 0 90px -30px rgba(141, 162, 255, 0.35);
}
.viewer__main {
    display: grid;
    grid-template-rows: minmax(0, 1fr) auto;
    gap: 0.75rem;
    min-width: 0;
    min-height: 0;
}
.viewer__stage {
    position: relative;
    display: grid;
    place-items: center;
    min-width: 0;
    min-height: 0;
}
.viewer__video,
.viewer__img {
    display: block;
    border-radius: 10px;
    background: #000;
    box-shadow: 0 30px 70px -30px #000;
}
.viewer__video[hidden],
.viewer__img[hidden] { display: none; }
.viewer__strip {
    display: flex;
    gap: 6px;
    overflow-x: auto;
    padding: 3px;
    scrollbar-width: thin;
}
.viewer__thumb {
    flex: none;
    height: 60px;
    padding: 0;
    border: 0;
    border-radius: 6px;
    overflow: hidden;
    background: #000;
    cursor: pointer;
    opacity: 0.5;
    transition: opacity 0.2s ease, box-shadow 0.2s ease;
}
.viewer__thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
.viewer__thumb:hover,
.viewer__thumb:focus-visible { opacity: 0.9; outline: none; }
.viewer__thumb.is-on { opacity: 1; box-shadow: 0 0 0 2px #8da2ff; }
.viewer__info {
    min-height: 0;
    overflow-y: auto;
    padding: 2.6rem 0.4rem 0.5rem 0;
    scrollbar-width: thin;
}
.viewer__kicker {
    font-family: var(--font-mono);
    font-size: 0.66rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #8e96a8;
}
.viewer__title { margin-top: 0.25rem; }
.viewer__name {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 1.7rem;
    line-height: 1.1;
    letter-spacing: -0.02em;
}
.viewer__count { font-family: var(--font-mono); font-size: 0.75rem; color: #8e96a8; }
.viewer__caption { margin-top: 0.5rem; font-size: 0.9rem; color: #8da2ff; }
.viewer__line { margin-top: 0.7rem; font-size: 0.88rem; line-height: 1.55; color: #b9c0cf; }
.viewer__stack { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-top: 0.9rem; }
.viewer__stack li {
    padding: 0.24rem 0.6rem;
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 999px;
    font-family: var(--font-mono);
    font-size: 0.7rem;
    color: #b9c0cf;
}
.viewer__actions { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 1rem; }
.viewer__note { margin-top: 0.8rem; font-size: 0.78rem; line-height: 1.45; color: #f2c069; }
.viewer .proj-btn { color: #eef0f6; border-color: rgba(255, 255, 255, 0.22); }
.viewer .proj-btn:hover,
.viewer .proj-btn:focus-visible { border-color: rgba(141, 162, 255, 0.6); background: rgba(141, 162, 255, 0.14); }
.viewer .proj-btn--ask::before { background: #5ee6c8; box-shadow: 0 0 8px #5ee6c8; }
.viewer__close,
.viewer__nav {
    position: absolute;
    z-index: 10;
    display: grid;
    place-items: center;
    width: 2.6rem;
    height: 2.6rem;
    border: 1px solid rgba(255, 255, 255, 0.22);
    border-radius: 50%;
    background: rgba(10, 12, 17, 0.6);
    color: #eef0f6;
    line-height: 1;
    cursor: pointer;
    transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.viewer__close:hover,
.viewer__nav:hover { background: #eef0f6; color: #0a0c11; border-color: #eef0f6; }
.viewer__close { top: 0.8rem; right: 0.8rem; font-size: 1.4rem; }
.viewer__nav { top: 50%; transform: translateY(-50%); font-size: 1.5rem; }
.viewer__nav--prev { left: 0.5rem; }
.viewer__nav--next { right: 0.5rem; }

/* Footer ----------------------------------------------------------------- */

.footer {
    border-top: 1px solid var(--line);
    padding-block: 1.75rem 2.5rem;
    font-size: 0.82rem;
    color: var(--fg-3);
}

.footer__inner {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}

.footer__top { text-decoration: none; }
.footer__top:hover { color: var(--fg); }

/* Responsive ------------------------------------------------------------- */

/* Just above the phone menu the full nav, the short CV button and the
   theme toggle share the bar: the monogram stands for the name there. */
@media (min-width: 861px) and (max-width: 1000px) {
    .topbar__name { display: none; }
}

@media (max-width: 1024px) {
    .skill { grid-template-columns: 13rem minmax(0, 1fr); gap: 1.25rem 1.5rem; }
    .work--lead { grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); }
    .work--lead.work--flip { grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr); }
}

@media (max-width: 860px) {
    .topbar { top: 0.75rem; }
    .topbar__nav {
        display: none;
        position: absolute;
        top: calc(100% + 0.6rem);
        left: 0;
        right: 0;
        flex-direction: column;
        align-items: stretch;
        gap: 0.15rem;
        padding: 0.6rem;
        border: 1px solid var(--line);
        border-radius: var(--radius);
        background: color-mix(in srgb, var(--bg-2) 92%, transparent);
        backdrop-filter: blur(18px);
        -webkit-backdrop-filter: blur(18px);
        box-shadow: var(--shadow);
    }
    .topbar__nav.is-open { display: flex; }
    .topbar__link { padding: 0.75rem 0.9rem; font-size: 1rem; border-radius: var(--radius-sm); }
    .topbar__menu { display: inline-flex; }
    .topbar__name { display: none; }

    /* One column: the name, then the head with its chat and the fit check
       right under it (user, 2026-09-27), then the rest. */
    .hero__grid {
        grid-template-columns: minmax(0, 1fr);
        grid-template-rows: auto;
        grid-template-areas: "head" "visual" "talk" "fit" "copy";
        gap: 1.5rem;
    }
    .hero__head { padding-top: 0; }
    /* A smaller head in a taller curtain (user, 2026-09-27: the head was
       bigger than the curtain); avatar.js reads --head-scale. */
    .twin__stage { --head-scale: 0.72; align-self: stretch; height: clamp(320px, 86vw, 420px); margin: -1.5rem 0 0; }
    .talk { height: 17rem; max-height: none; margin-top: calc(-1.5rem - 2.35rem); }
    .talk__input, .fitbox__input { font-size: 1rem; } /* 16px: iOS does not zoom the page on focus */

    /* The comparison table as a list of cards. */
    .fitr__table { min-width: 0; }
    .fitr__table thead { display: none; }
    .fitr__table tr { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 0.25rem 0.6rem; padding: 0.7rem 0.8rem; border-bottom: 1px solid var(--line); }
    .fitr__table tbody tr:last-child { border-bottom: 0; }
    .fitr__table td { display: block; padding: 0; border: 0; width: auto; }
    .fitr__table .fitr__n { grid-row: 1; padding-top: 0.15rem; }
    .fitr__table .fitr__req { grid-row: 1; }
    .fitr__table .fitr__st { grid-row: 1; }
    .fitr__table .fitr__ev { grid-column: 2 / -1; font-size: 0.86rem; }
    .fitr__table tbody tr:hover td { background: transparent; }

    .sec__head { grid-template-columns: minmax(0, 1fr); }
    .sec__intro { text-align: left; }

    .skill { grid-template-columns: minmax(0, 1fr); gap: 0.9rem; padding: 1.2rem 1.25rem 1.3rem; }
    .skill__side { flex-direction: row; align-items: baseline; gap: 0.7rem; }
    .skill--primary .skill__name { font-size: 1.3rem; }

    .spec { padding-inline: 1.25rem; }
    .spec__row { grid-template-columns: minmax(0, 1fr); gap: 0.4rem; }

    .timeline { padding-left: 1.5rem; }
    .job::before { left: calc(-1.5rem + 0.45rem - 4.5px); }
    .job__card { padding: 1.25rem 1.25rem 1.35rem; }
    .job__meta { align-items: flex-start; flex-direction: row; flex-wrap: wrap; gap: 0.5rem 0.9rem; }

    .edu { grid-template-columns: minmax(0, 1fr); }
    .cta { grid-template-columns: minmax(0, 1fr); }

    /* The portfolio in one column: a lead's media above its text. */
    .works { grid-template-columns: minmax(0, 1fr); }
    .work--lead,
    .work--lead.work--flip { grid-template-columns: minmax(0, 1fr); gap: 1.25rem; padding-block: 0.5rem; }
    .work--lead.work--flip .work__media { order: 0; }
    /* A wide card in one column: the text, then its diagram, then its
       buttons last. */
    .work--wide.work--system { grid-template-columns: minmax(0, 1fr); row-gap: 0; }
    .work--wide.work--system > .work__body { display: contents; }
    .work--wide.work--system > .work__icon { margin-bottom: 1rem; }
    .work--wide.work--system > .arch,
    .work--wide.work--system > .work__flow { order: 1; margin-top: 1.1rem; }
    .work--wide.work--system .work__actions { order: 2; }
    .work__flow--column { flex-direction: row; flex-wrap: wrap; align-items: center; justify-self: start; width: auto; gap: 0.5rem 0.9rem; }
    .work__flow--column li { padding-block: 0.36rem; text-align: left; }
    .work__flow--column li:not(:last-child):not(.is-row-end)::after { top: 50%; left: auto; right: calc(-0.9rem + 3px); width: calc(0.9rem - 6px); height: 1px; }
    .arch { grid-template-columns: minmax(0, 1fr); gap: 1.5rem; }
    .arch__col + .arch__col::after { top: -1.05rem; left: 1.2rem; width: 1px; height: 0.75rem; }
    .works--tiles { grid-template-columns: repeat(auto-fill, minmax(min(100%, 13rem), 1fr)); }

    /* The viewer: the clip on top, its clips under it, the project under
       them; the whole dialog scrolls. */
    .viewer { padding: 0.5rem; }
    .viewer[open] { place-items: start center; overflow-y: auto; }
    .viewer__panel { grid-template-columns: minmax(0, 1fr); gap: 1rem; height: auto; padding: 3.4rem 0.75rem 1rem; }
    .viewer__info { overflow: visible; padding: 0 0.2rem; }
    .viewer__close { top: 0.5rem; right: 0.5rem; }
    .viewer__nav { width: 2.3rem; height: 2.3rem; }
    .viewer__thumb { height: 52px; }

}

@media (max-width: 520px) {
    .brief { --env-w: 124px; gap: 1.1rem; padding: 3.6rem 0.5rem 0.6rem; }
    .brief__title { font-size: 1.25rem; }
    /* The fit form: the field on its own line, the button under it. */
    .fitbox { padding: 0.95rem 0.95rem 0.9rem; }
    .fitbox__form { flex-wrap: wrap; padding: 0.3rem 0.3rem 0.3rem 0.8rem; }
    .fitbox__input { flex-basis: calc(100% - 2.2rem); }
    .fitbox__go { flex: 1 1 100%; justify-content: center; margin-left: -0.5rem; }

    :root { --radius: 16px; }
    .talk { height: 18rem; }
    .talk__head { padding-inline: 1rem 0.9rem; }
    .talk__log { padding-inline: 1rem; }
    .talk__form { padding-left: 0.7rem; }
    .fit { gap: 0.3rem 0.7rem; padding: 0.65rem 0.7rem; }
    .fit__ring { width: 3.9rem; height: 3.9rem; align-self: start; }
    .fit__ring .ring__num { font-size: 1.15rem; }
    .fit__ring .ring__of { bottom: 0.7rem; }
    .fitr { width: calc(100vw - 1rem); max-height: calc(100vh - 1rem); }
    .fitr__card { padding: 1.1rem 1rem 1.1rem; }
    .fitr__head { grid-template-columns: auto minmax(0, 1fr); }
    .fitr__close { grid-column: 2; grid-row: 1; justify-self: end; }
    .fitr__lead { grid-column: 1 / -1; }
    .fitr__ring { width: 5.2rem; height: 5.2rem; }
    .fitr__ring .ring__num { font-size: 1.5rem; }
    .fitr__ring .ring__of { bottom: 1rem; font-size: 0.55rem; }
    .hero { padding-top: 6rem; }
    .hero__title { font-size: clamp(2.1rem, 10.5vw, 2.6rem); }
    .cta__facts > div { grid-template-columns: minmax(0, 1fr); gap: 0.15rem; }

    /* A half's phone above its text; tiles two by two. */
    .work--half { grid-template-columns: minmax(0, 1fr); }
    .chapter__icon { width: 2.6rem; height: 2.6rem; border-radius: 12px; }
    .works--tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 0.85rem; }
    .work--tile .work__name { font-size: 1.05rem; }
    .work--tile .work__line { font-size: 0.82rem; }
    .work--tile .work__kicker { font-size: 0.62rem; }
    .work--tile .work__stack { display: none; }
    .device--phone .device__body { border-radius: 28px; }
    .device--phone .device__screen { border-radius: 22px; }
    .work__media--pair { padding: 0 7% 10% 0; }
    .device--mini { width: 27%; }
    .device__hint { right: 8px; bottom: 8px; width: 26px; height: 26px; }
    .device__hint svg { width: 11px; height: 11px; }
}

/* Short CV ---------------------------------------------------------------- */

/* The whole CV as one classic document, over the page (cv.js): a sheet of
   paper in both themes, set like a printed CV (a column of section labels,
   the content beside it), in the site's own type and colours. */
html.cv-open { overflow: hidden; }
.cvdoc {
    --paper: #fcfcfa;
    --ink: #141924;
    --ink-2: #454e60;
    --ink-3: #737b8d;
    --rule: #e3e6ed;
    --tint: #eef1f6;
    --cv-accent: #3d4fcf;
    --cv-accent-2: #0b8f7b;
    width: 100vw;
    height: 100vh;
    height: 100dvh;
    max-width: none;
    max-height: none;
    margin: 0;
    padding: clamp(0.75rem, 4.5vw, 3.5rem) clamp(0.5rem, 3vw, 2rem) clamp(2rem, 6vw, 4.5rem);
    border: 0;
    background: rgba(6, 8, 13, 0.8);
    -webkit-backdrop-filter: blur(10px) saturate(1.1);
    backdrop-filter: blur(10px) saturate(1.1);
    color: var(--ink);
    overflow-y: auto;
    overscroll-behavior: contain;
}
.cvdoc::backdrop { background: transparent; }
.cvdoc__close {
    position: fixed;
    top: 0.9rem;
    right: 0.9rem;
    z-index: 1;
    display: grid;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    padding: 0;
    border: 1px solid rgba(255, 255, 255, 0.22);
    border-radius: 50%;
    background: rgba(16, 19, 28, 0.78);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    color: #eef0f6;
    cursor: pointer;
    transition: background 0.2s, border-color 0.2s;
}
.cvdoc__close:hover { background: rgba(36, 41, 58, 0.92); border-color: rgba(255, 255, 255, 0.42); }
.cvdoc__close:focus-visible { outline: 2px solid #8da2ff; outline-offset: 2px; }

.cvdoc__sheet {
    position: relative;
    width: min(100%, 880px);
    margin: 0 auto;
    padding: clamp(1.6rem, 5.5vw, 3.6rem) clamp(1.15rem, 5.5vw, 3.9rem) clamp(2rem, 5vw, 3.4rem);
    border-radius: 6px;
    background: var(--paper);
    box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.05), 0 50px 100px -40px rgba(0, 0, 0, 0.85);
    font-family: var(--font-text);
    font-size: 0.875rem;
    line-height: 1.55;
    color: var(--ink-2);
    transform-origin: 0 0;
}
.cvdoc__sheet p { margin: 0; }

.cvdoc__head {
    padding-bottom: 1.35rem;
    border-bottom: 2px solid var(--ink);
}
.cvdoc__name {
    margin: 0;
    font-family: var(--font-display);
    font-variation-settings: "opsz" 96;
    font-weight: 700;
    font-size: clamp(2.1rem, 5vw, 3rem);
    line-height: 1;
    letter-spacing: -0.045em;
    color: var(--ink);
}
.cvdoc__role {
    width: fit-content;
    margin-top: 0.5rem !important;
    font-family: var(--font-display);
    font-variation-settings: "opsz" 48;
    font-weight: 500;
    font-size: clamp(1.08rem, 2.2vw, 1.3rem);
    letter-spacing: -0.02em;
    line-height: 1.2;
    background: linear-gradient(95deg, var(--cv-accent), var(--cv-accent-2));
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}
.cvdoc__contacts {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 1.3rem;
    margin: 1.15rem 0 0;
    padding: 0;
    list-style: none;
    font-size: 0.8rem;
    color: var(--ink-2);
}
.cvdoc__contacts li { display: inline-flex; align-items: center; gap: 0.4rem; white-space: nowrap; }
.cvdoc__contacts svg {
    flex: none;
    width: 14px;
    height: 14px;
    fill: none;
    stroke: var(--cv-accent);
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.cvdoc__contacts a {
    color: var(--ink);
    text-decoration: none;
    background: linear-gradient(currentColor, currentColor) 0 100% / 0 1px no-repeat;
    transition: background-size 0.25s;
}
.cvdoc__contacts a:hover, .cvdoc__contacts a:focus-visible { background-size: 100% 1px; }
.cvdoc__open {
    display: inline-flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0 0.4rem;
    margin-top: 1rem !important;
    padding: 0.38rem 0.85rem 0.4rem 0.75rem;
    border-radius: 999px;
    background: color-mix(in srgb, var(--cv-accent-2) 9%, transparent);
    font-size: 0.8rem;
    line-height: 1.45;
}
.cvdoc__open::before {
    content: "";
    flex: none;
    align-self: center;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--cv-accent-2);
}

.cvdoc__sec { padding-top: 1.6rem; }
/* A section's label, then a hairline to the margin. */
.cvdoc__h {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    margin: 0 0 0.85rem;
    font-family: var(--font-mono);
    font-size: 0.68rem;
    font-weight: 500;
    letter-spacing: 0.14em;
    line-height: 1.4;
    text-transform: uppercase;
    color: var(--cv-accent);
}
.cvdoc__h::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--rule);
}
.cvdoc__body { min-width: 0; }
.cvdoc__body > * + * { margin-top: 0.55rem !important; }
.cvdoc__sheet b { font-weight: 600; color: var(--ink); }
.cvdoc__tagline, .cvdoc__note { font-style: italic; color: var(--ink-3); }
.cvdoc__keys { color: var(--ink); word-spacing: 0.04em; }

.cvdoc__list {
    display: grid;
    gap: 0.34rem;
    margin: 0;
    padding: 0;
    list-style: none;
}
.cvdoc__list li { position: relative; padding-left: 1.05rem; }
/* The marquee's diamond, as the bullet. */
.cvdoc__list li::before {
    content: "";
    position: absolute;
    left: 0.12rem;
    top: 0.6em;
    width: 5px;
    height: 5px;
    border-radius: 1px;
    background: var(--cv-accent-2);
    transform: rotate(45deg);
}

.cvdoc__job + .cvdoc__job { margin-top: 1.3rem !important; }
.cvdoc__job-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.1rem 1.25rem;
    margin-bottom: 0.5rem;
}
.cvdoc__job-title {
    margin: 0;
    font-size: 0.97rem;
    font-weight: 600;
    letter-spacing: -0.005em;
    line-height: 1.35;
    color: var(--ink);
}
.cvdoc__org { font-weight: 400; color: var(--ink-2); }
.cvdoc__date {
    font-family: var(--font-mono);
    font-size: 0.7rem;
    letter-spacing: 0.02em;
    white-space: nowrap;
    color: var(--ink-3);
}
.cvdoc__text { color: var(--ink-2); }
.cvdoc__job > .cvdoc__dirs, .cvdoc__job > .cvdoc__text + .cvdoc__dirs { margin-top: 0.5rem; }
.cvdoc__dirs { font-size: 0.82rem; color: var(--ink-3); }
.cvdoc__chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    margin: 0.7rem 0 0;
    padding: 0;
    list-style: none;
}
.cvdoc__chips li {
    padding: 0.12rem 0.5rem;
    border-radius: 5px;
    background: var(--tint);
    font-family: var(--font-mono);
    font-size: 0.66rem;
    line-height: 1.6;
    color: var(--ink-2);
}

.cvdoc__row + .cvdoc__row { margin-top: 0.45rem !important; }
.cvdoc__row i { font-style: normal; font-weight: 600; color: var(--ink-3); }

.cvdoc__projects { gap: 0.6rem; }
.cvdoc__stack {
    display: block;
    margin-top: 0.12rem;
    font-family: var(--font-mono);
    font-size: 0.66rem;
    line-height: 1.6;
    color: var(--ink-3);
}

.cvdoc__edu {
    display: grid;
    grid-template-columns: 6.25rem minmax(0, 1fr);
    gap: 0.6rem 1rem;
}
.cvdoc__edu > * + * { margin-top: 0 !important; }
.cvdoc__year {
    padding-top: 0.12rem;
    font-family: var(--font-mono);
    font-size: 0.72rem;
    color: var(--ink-3);
}
.cvdoc__desc { margin-top: 0.15rem !important; font-size: 0.83rem; }

@media (max-width: 640px) {
    .cvdoc { padding-inline: 0; padding-top: 3.9rem; }
    .cvdoc__sheet { border-radius: 4px; font-size: 0.86rem; }
    .cvdoc__contacts { gap: 0.35rem 1rem; }
    .cvdoc__contacts li { white-space: normal; }
    .cvdoc__edu { grid-template-columns: 4.9rem minmax(0, 1fr); }
}

/* Print ------------------------------------------------------------------ */

@media print {
    :root {
        --bg: #fff; --bg-2: #fff; --bg-3: #f2f2f2;
        --fg: #111; --fg-2: #333; --fg-3: #666;
        --line: #ddd; --line-2: #bbb;
        --card: #fff; --card-hover: #fff; --chip: #fff;
        --accent: #3344aa; --accent-2: #0d7f6d;
        --shadow: none;
    }
    /* Paper: a white page and white margins, whatever the theme on screen
       (a dark colour scheme prints dark margins in Chrome). */
    :root, :root[data-theme] { color-scheme: light; background: #fff; }
    body::before, body::after { display: none; }
    .topbar, .marquee, .twin__canvas, .twin__stage, .talk, .fitbox, .brief, .cta__fit, .sec--work, .footer { display: none; }
    .hero { padding-top: 1rem; }
    .hero__grid { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto; grid-template-areas: "head" "copy"; }
    .sec { padding-block: 1.25rem; break-inside: avoid; }
    .card { break-inside: avoid; }
    html.js-rv .rv { opacity: 1; transform: none; }
    .hero__head.fade, .hero__copy.fade, .fitbox.fade { opacity: 1; }

    /* With the short CV open, the print is the CV alone, one clean document
       (there is no PDF download, on purpose: the browser's print saves one). */
    @page { margin: 10mm 12mm; }
    html.cv-open body > :not(.cvdoc) { display: none !important; }
    html.cv-open .cvdoc { position: static; width: auto; height: auto; padding: 0; overflow: visible; background: none; -webkit-backdrop-filter: none; backdrop-filter: none; }
    .cvdoc__close { display: none; }
    .cvdoc__sheet { width: auto; padding: 0; border-radius: 0; background: #fff; box-shadow: none; font-size: 9pt; line-height: 1.4; }
    .cvdoc__head { padding-bottom: 9pt; }
    .cvdoc__name { font-size: 24pt; }
    .cvdoc__role { background: none; color: var(--cv-accent); -webkit-text-fill-color: currentColor; font-size: 12.5pt; }
    .cvdoc__contacts { margin-top: 8pt; font-size: 8.4pt; }
    .cvdoc__open { margin-top: 7pt !important; font-size: 8.4pt; }
    .cvdoc__sec { padding-top: 11pt; }
    .cvdoc__h { margin-bottom: 6pt; }
    .cvdoc__list { gap: 2.5pt; }
    .cvdoc__job + .cvdoc__job { margin-top: 9pt !important; }
    .cvdoc__job-head { margin-bottom: 3pt; }
    .cvdoc__job-title { font-size: 10pt; }
    .cvdoc__body > * + * { margin-top: 4pt !important; }
    .cvdoc__job-head, .cvdoc__row, .cvdoc__list li, .cvdoc__edu > * { break-inside: avoid; }
    .cvdoc__h, .cvdoc__job-head { break-after: avoid; }
    .cvdoc__contacts, .cvdoc__open, .cvdoc__chips li { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* Reduced motion --------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    html.js-rv .rv { opacity: 1; transform: none; transition: none; }
    .marquee__track { animation: none; flex-wrap: wrap; width: 100%; }
    .marquee ul[aria-hidden="true"] { display: none; }
    .marquee ul { flex-wrap: wrap; gap: 0.75rem 1.5rem; }
    .pulse::after { animation: none; }
    .talk__dot, .fitbox__spark, .fitbox--flash, .fitbox__steps i, .fitbox__go:disabled::before { animation: none; }
    .brief__paper, .brief__glow, .brief__env, .brief::after { animation: none; }
    .talk__dots i { animation: none; opacity: 0.6; }
    .work__flow li, .arch__col li, .work.is-called { animation: none; }
    *, *::before, *::after { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}
