/* pages.css — page-specific layouts (home, bio, policy, projects, skills,
   cloud, AI). The global reflow/responsive block is at the very end so it
   overrides the base rules in every earlier file. */

/* =====================  LANDING / HOME  ===================== */
.landing {
    padding: 24px 10px 14px 10px;
}

/* =====================  HOME DASHBOARD  ===================== */
/* Hero banner over the workspace photo, with a dark left-to-right wash so the
   welcome text stays readable. */
.home-hero {
    position: relative;
    display: flex;
    align-items: flex-end;
    min-height: 260px;
    margin-bottom: 18px;
    border-radius: 14px;
    overflow: hidden;
    border: 1px solid var(--panel-edge);
    box-shadow: 0 12px 34px rgba(0, 0, 0, 0.5);
    background-image:
        linear-gradient(90deg, rgba(6,10,8,0.94) 0%, rgba(6,10,8,0.75) 42%, rgba(6,10,8,0.28) 100%),
        url('../img/workspace.jpg');
    background-size: cover;
    background-position: center 40%;
}
.home-hero-inner { padding: 26px 30px; max-width: 620px; }
.home-hero-title {
    font-family: var(--font-display);
    font-size: 40pt;
    color: #fff;
    margin: 0 0 8px;
    line-height: 1;
}
.home-hero-lead {
    font-size: 12.5pt;
    line-height: 1.6;
    color: rgba(255, 255, 255, 0.9);
    margin: 0 0 18px;
}
.home-hero-cta { display: flex; gap: 12px; flex-wrap: wrap; }

/* Bento grid of section cards, each with its own accent colour (--c). */
.home-grid {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 16px;
}
.hcard-span3 { grid-column: span 3; }
.hcard-span2 { grid-column: span 2; }

.hcard {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: 20px 20px 22px;
    border-radius: 12px;
    border: 1px solid var(--panel-edge);
    border-top: 3px solid var(--c);
    background:
        linear-gradient(180deg, var(--sheen) 0%, rgba(255,255,255,0) 55%),
        var(--panel);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
    overflow: hidden;
    transition: transform 0.18s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}
/* soft colour wash in the top-right corner, tinted to the card's accent */
.hcard::before {
    content: "";
    position: absolute;
    top: -50px; right: -50px;
    width: 140px; height: 140px;
    background: radial-gradient(circle, color-mix(in srgb, var(--c) 30%, transparent) 0%, transparent 68%);
    pointer-events: none;
}
.hcard:hover {
    transform: translateY(-4px);
    border-color: var(--c);
    box-shadow: 0 16px 36px rgba(0, 0, 0, 0.55);
}


.hcard-kicker {
    font: 600 9.5pt var(--font-body);
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: var(--c);
    margin: 0 0 4px;
}
.hcard-title {
    font: 600 15pt var(--font-body);
    color: #fff;
    margin: 0 0 6px;
    line-height: 1.2;
}
.hcard-blurb {
    font-size: 10.5pt;
    line-height: 1.55;
    color: var(--text-soft);
    margin: 0;
    padding-right: 42px;    /* keep text clear of the arrow */
}

/* logo / icon strip (work, skills, projects) */
.hcard-media { display: flex; gap: 8px; margin-bottom: 14px; flex-wrap: wrap; }
.hcard-logo {
    width: 34px; height: 34px;
    display: grid; place-items: center;
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.92);
    border: 1px solid rgba(255, 255, 255, 0.25);
}
.hcard-logo img { width: 22px; height: 22px; object-fit: contain; }
.hcard-logo-dark { background: #1b1f23; border-color: rgba(255, 255, 255, 0.18); }
.hcard-logo-dark i { color: #fff; font-size: 18px; }

/* single glyph tile (policy, contact) */
.hcard-glyph {
    width: 48px; height: 48px;
    display: grid; place-items: center;
    margin-bottom: 14px;
    border-radius: 12px;
    font-size: 22px;
    color: var(--c);
    background: color-mix(in srgb, var(--c) 16%, transparent);
    border: 1px solid color-mix(in srgb, var(--c) 42%, transparent);
}

/* image / gif thumb (community, top of card) */
.hcard-img {
    width: 100%;
    height: 124px;
    object-fit: cover;
    border-radius: 8px;
    margin-bottom: 14px;
    border: 1px solid var(--panel-edge);
    background: #000;
}

/* Projects and AI: media on the left, text on the right. The gif (4:3) and the
   short (9:16) are both pinned to the SHARED_MEDIA_HEIGHT (160px) so they line
   up exactly, with their widths following each aspect ratio. */
.hcard-projects,
.hcard-ai {
    flex-direction: row;
    align-items: flex-start;
    gap: 16px;
}
.hcard-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.hcard-side-media { flex: 0 0 auto; margin: 0; }

.hcard-projects .hcard-side-media {
    box-sizing: border-box;
    height: 160px;
    width: auto;                /* 4:3 gif -> ~213px wide, uncropped */
    border-radius: 8px;
    border: 1px solid var(--panel-edge);
    background: #000;
}
/* The Grocy card's 9:16 clip fills the card height; its width follows the
   portrait ratio, giving a neat thumbnail beside the text column. */
.hcard-ai .hcard-side-media {
    box-sizing: border-box;
    align-self: stretch;
    height: 160px;
    min-height: 160px;
    width: auto;
    aspect-ratio: 9 / 16;
    object-fit: cover;
    border-radius: 8px;
    border: 1px solid var(--panel-edge);
    background: #000;
}

/* While a video is playing, the card's cover link is disabled so clicks around
   the video do not navigate; only the arrow (re-enabled) still links out. */
.hcard.is-playing .hcard-link { pointer-events: none; }
.hcard.is-playing .hcard-arrow { pointer-events: auto; }

/* stretched arrow link — the whole card is clickable, arrow shown bottom-right */
.hcard-link { position: absolute; inset: 0; z-index: 1; text-decoration: none; }
.hcard-arrow {
    position: absolute;
    right: 16px; bottom: 16px;
    width: 34px; height: 34px;
    display: grid; place-items: center;
    border-radius: 50%;
    color: var(--c);
    background: color-mix(in srgb, var(--c) 16%, transparent);
    border: 1px solid color-mix(in srgb, var(--c) 45%, transparent);
    transition: transform 0.2s ease, background 0.2s ease, color 0.2s ease;
}
.hcard:hover .hcard-arrow { background: var(--c); color: #0b1410; transform: translateX(3px); }

@media (max-width: 760px) {
    .home-grid { grid-template-columns: 1fr; }
    .hcard-span3, .hcard-span2 { grid-column: span 1; }
    .home-hero { min-height: 210px; }
    .home-hero-title { font-size: 30pt; }
    .home-hero-inner { padding: 20px 20px; }
}

/* =====================  BIO  ===================== */
.bio { padding: 24px 10px 14px 10px; }

.bio-panel {
    background:
        linear-gradient(180deg, var(--sheen) 0%, rgba(255,255,255,0) 40%),
        var(--panel);
    border: 1px solid var(--panel-edge);
    border-top: 2px solid var(--accent);
    border-radius: 10px;
    padding: 24px 28px;
    margin-bottom: 22px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
}

.bio-heading {
    font-family: var(--font-display);
    font-size: 26pt;
    color: #fff;
    margin: 0 0 16px 0;
    padding-bottom: 8px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}

.bio-body { font-size: 12pt; line-height: 1.7; color: var(--text-soft); }
.bio-body p { margin: 0 0 16px 0; }
.bio-body a { color: var(--accent); }
.bio-body a:hover { color: #fff; }

/* ---- Bio figures / placeholder images ---- */
.bio-figure {
    width: 230px;
    margin: 4px 0 16px 0;
    border-radius: 8px;
    overflow: hidden;
    border: 1px solid var(--panel-edge);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.5);
    background: #000;
}
.bio-figure-right { float: right; margin-left: 24px; }
.bio-figure-left  { float: left;  margin-right: 24px; }
.bio-figure img { display: block; width: 100%; height: auto; cursor: zoom-in; }

/* Larger variant for the landing page Jane's Walk photo. */
.bio-figure-lg { width: 360px; max-width: 100%; }
.bio-figure figcaption {
    font-size: 8.5pt;
    font-style: italic;
    color: rgba(255, 255, 255, 0.6);
    padding: 7px 10px;
    text-align: center;
}
/* When the suggested image is missing, this renders a tidy labelled
   placeholder instead of a broken image. */
.bio-figure.placeholder {
    min-height: 150px;
    display: flex;
    align-items: flex-end;
    background:
        repeating-linear-gradient(45deg, rgba(255,255,255,0.03) 0 12px, rgba(255,255,255,0.06) 12px 24px),
        linear-gradient(160deg, var(--accent-deep) 0%, #14241c 100%);
}
.bio-figure.placeholder figcaption {
    width: 100%;
    background: rgba(0, 0, 0, 0.45);
    color: rgba(255, 255, 255, 0.85);
    font-style: normal;
}

@media (max-width: 640px) {
    .bio-figure-left, .bio-figure-right { float: none; margin: 0 auto 18px auto; }
}

/* =====================  PUBLIC POLICY PANELS  ===================== */
.policy-kicker {
    font-family: var(--font-body);
    font-size: 9.5pt;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: var(--accent);
    margin-bottom: 4px;
}

/* Logo (e.g. the LUS logo) scaled down and floated neatly into the panel. */
.policy-logo {
    float: right;
    width: 96px;
    height: auto;
    max-height: 96px;
    margin: 0 0 12px 20px;
    border-radius: 8px;
}
/* Left-floated variant, used on the Community page so the logo and the
   Jane's Walk photo sit on opposite sides instead of crowding together. */
.policy-logo-left {
    float: left;
    margin: 0 20px 12px 0;
}

.policy-links {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    margin-top: 16px;
}

/* Orange accent for the AI essay panel, so it matches the cards above instead
   of using the site-wide green accent. */
.bio-panel--orange { border-top-color: #f0a24b; }
.bio-panel--orange .bio-body a { color: #f0a24b; }
.bio-panel--orange .bio-body a:hover { color: #fff; }

/* =====================  POLICY / MUSIC / EDUCATION  =====================
   The three pages behind the "+" nav pill. Each pane sets its own --accent (see
   tokens.css), so the bubbles and module list below recolour to their page
   without any per-page rules here. The player styling lives in music.css. */

/* ---- Qualification bubbles: the credential(s) behind a section, between its
        heading and its text. One on Policy, two side by side on Music. They
        pick up the section's --accent, so each set is tinted to its subject. */
.quals {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin: 0 0 20px 0;
}
.qual {
    display: inline-flex;
    align-items: center;
    gap: 13px;
    padding: 11px 20px 11px 12px;
    border-radius: 14px;
    font-family: var(--font-body);
    border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
    background:
        linear-gradient(180deg, rgba(255, 255, 255, 0.10) 0%, rgba(255, 255, 255, 0) 55%),
        color-mix(in srgb, var(--accent) 11%, rgba(255, 255, 255, 0.04));
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.4),
                0 0 20px -8px var(--accent),
                inset 0 1px 0 rgba(255, 255, 255, 0.14);
}
.qual-ico {
    flex: 0 0 auto;
    width: 38px;
    height: 38px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    font-size: 14pt;
    color: #fff;
    background: linear-gradient(180deg, var(--accent) 0%, var(--accent-deep) 100%);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
}
.qual-text { display: block; }
.qual-title {
    display: block;
    font-size: 11.5pt;
    font-weight: 600;
    color: #fff;
    line-height: 1.25;
}
.qual-org {
    display: block;
    font-size: 9.5pt;
    color: var(--text-soft);
    margin-top: 1px;
}
.qual-date {
    display: block;
    font-size: 8.5pt;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    color: var(--accent);
    margin-top: 3px;
}
@media (max-width: 700px) {
    .qual { width: 100%; padding: 10px 14px 10px 10px; }
}

/* The twelve course modules, as a compact two/three-column list inside the
   policy panel. */
.more-modules {
    list-style: none;
    margin: 0 0 16px 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 7px 16px;
}
.more-modules li {
    position: relative;
    padding-left: 18px;
    font-size: 11pt;
    line-height: 1.45;
}
.more-modules li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.55em;
    width: 6px;
    height: 6px;
    border-radius: 2px;
    background: var(--accent);
}

/* Cloud explainer page (colour vars are defined in tokens.css). */
#cloud-page { padding: 24px 10px 14px 10px; }

/* "How it fits together" reuses the standard .bio-heading style so the page
   carries no one-off heading of its own. */

/* ---- Shared colour legend (one definition for all three charts) ---- */
.cloud-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 10px 20px;
    margin-top: 18px;
    padding: 14px 16px;
    border: 1px solid var(--panel-edge);
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.04);
    font-size: 11pt;
    color: var(--text-soft);
}
.cloud-legend-item { display: inline-flex; align-items: center; gap: 8px; }
.cloud-legend-item strong { color: #fff; }
.cloud-swatch {
    width: 16px; height: 16px;
    border-radius: 4px;
    border: 2px solid;
    flex: 0 0 auto;
}
.cloud-swatch--npm   { background: var(--c-npm-fill);   border-color: var(--c-npm); }
.cloud-swatch--pip   { background: var(--c-pip-fill);   border-color: var(--c-pip); }
.cloud-swatch--infra { background: var(--c-infra-fill); border-color: var(--c-infra); }

/* Green "step complete" chip, shown in the legend and inside build-step nodes.
   The check glyph means colour is never the only signal. */
.step-done {
    display: inline-block;
    min-width: 16px; height: 16px; line-height: 16px;
    padding: 0 3px;
    border-radius: 3px;
    background: var(--accent-deep);
    color: #fff !important;
    font-size: 10px;
    font-weight: bold;
    text-align: center;
    vertical-align: middle;
}

/* ---- Collapsible chart panels ---- */
.cloud-chart { padding: 0; overflow: hidden; }

.cloud-chart-head {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 16px 20px;
    cursor: pointer;
    user-select: none;
}
.cloud-chart-head:hover .cloud-chart-title { color: var(--accent); }
.cloud-chart-head:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
}
.cloud-chart-headtext { flex: 1 1 auto; min-width: 0; }
.cloud-chart-title {
    font-family: var(--font-display);
    font-size: 17pt;
    color: #fff;
    margin: 0;
    transition: color 0.2s ease;
}
.cloud-chart-sub {
    font-size: 10.5pt;
    color: var(--text-soft);
    margin-top: 3px;
}
.cloud-tag {
    display: inline-block;
    vertical-align: middle;
    margin-left: 8px;
    padding: 1px 8px;
    border-radius: 999px;
    border: 1px solid var(--panel-edge);
    background: rgba(255, 255, 255, 0.06);
    font-family: var(--font-body);
    font-size: 8.5pt;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: var(--text-soft);
}

/* Static, representative header numbers; stay visible when collapsed. */
.cloud-stats { display: flex; gap: 18px; flex: 0 0 auto; }
.cloud-stat { display: flex; flex-direction: column; align-items: center; line-height: 1.1; }
.cloud-stat b { font-size: 15pt; color: var(--accent); }
.cloud-stat span {
    font-size: 8.5pt;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-soft);
    margin-top: 2px;
}

.cloud-caret {
    flex: 0 0 auto;
    color: var(--text-soft);
    transition: transform 0.2s ease;
}
.cloud-chart.collapsed .cloud-caret { transform: rotate(-90deg); }

/* ---- Chart body: light card behind the diagram, with a spinner until ready ---- */
.cloud-chart-body { position: relative; padding: 0 20px 20px 20px; }

.cloud-scroll {
    position: relative;
    min-height: 170px;
    padding: 18px;
    border-radius: 10px;
    background: #f3f6f5;
    border: 1px solid #d9d9d9;
    overflow-x: auto;          /* scroll on narrow screens, never shrink to unreadable */
    text-align: center;
}
#cloud-page .mmd svg { display: block; margin: 0 auto; max-width: none; height: auto; }

/* Reinforce the ecosystem colours on the rendered SVG nodes (CSS wins with
   !important even if a Mermaid build ignores the var() classDef). */
#cloud-page .node.npm rect, #cloud-page .node.npm polygon,
#cloud-page .node.npm path, #cloud-page .node.npm circle,
#cloud-page .node.npm ellipse {
    fill: var(--c-npm-fill) !important; stroke: var(--c-npm) !important;
}
#cloud-page .node.pip rect, #cloud-page .node.pip polygon,
#cloud-page .node.pip path, #cloud-page .node.pip circle,
#cloud-page .node.pip ellipse {
    fill: var(--c-pip-fill) !important; stroke: var(--c-pip) !important;
}
#cloud-page .node.infra rect, #cloud-page .node.infra polygon,
#cloud-page .node.infra path, #cloud-page .node.infra circle,
#cloud-page .node.infra ellipse {
    fill: var(--c-infra-fill) !important; stroke: var(--c-infra) !important;
}
#cloud-page .node .nodeLabel { color: #111 !important; }

/* Keep the raw diagram source hidden (and out of the layout) until Mermaid has
   turned it into an SVG, so no pre-rendered text ever flashes. */
.cloud-chart:not(.rendered) .mmd { visibility: hidden; height: 0; overflow: hidden; }
.cloud-chart.rendered .mmd { visibility: visible; height: auto; }
.cloud-chart.rendered .cloud-spinner { display: none; }

.cloud-spinner {
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    color: #4a5d57;
}
.cloud-spinner-ring {
    width: 34px; height: 34px;
    border: 3px solid rgba(46, 139, 87, 0.25);
    border-top-color: var(--accent-deep);
    border-radius: 50%;
    animation: cloud-spin 0.8s linear infinite;
}
.cloud-spinner-text { font-size: 10.5pt; }

@keyframes cloud-spin { to { transform: rotate(360deg); } }

.cloud-illustrative-note {
    margin: 12px 2px 0 2px;
    font-size: 10pt;
    color: var(--text-soft);
}
.cloud-illustrative-note i { color: var(--accent); margin-right: 6px; }

/* No decorative motion anywhere in Part 1: drop the spinner spin too. */
@media (prefers-reduced-motion: reduce) {
    .cloud-spinner-ring { animation: none; }
    .cloud-caret { transition: none; }
}

@media (max-width: 600px) {
    #cloud-page { padding: 14px 4px 10px 4px; }
    .cloud-chart-head { flex-wrap: wrap; padding: 14px 16px; position: relative; }
    .cloud-chart-headtext { flex: 1 1 100%; padding-right: 28px; }
    .cloud-chart-title { font-size: 15pt; }
    .cloud-stats { flex: 1 1 100%; gap: 22px; margin-top: 4px; }
    .cloud-stat { align-items: flex-start; }
    .cloud-caret { position: absolute; top: 16px; right: 16px; }
    .cloud-chart-body { padding: 0 12px 16px 12px; }
    .cloud-scroll { padding: 12px; }
}

/* ---- StashPop article callout on the AI page ---- */
.stashpop-callout {
    margin: 0 0 18px;
    padding: 12px 16px;
    border-left: 4px solid #995ECE;
    background: rgba(153, 94, 206, 0.12);
    border-radius: 4px;
}
.stashpop-callout a { color: #F7C146; }

/* Landing quick-link cards are real <a> links now. */
a.landing-card { display: block; text-decoration: none; color: inherit; }

/* =====================  STASHPOP SHORT (landing page)  ===================== */
/* A vertical 9:16 tile that plays the YouTube short inline on click, the same
   interaction as the StashPop blog. Floated right in the Welcome panel; the
   click handler in script.js swaps the thumbnail for the embed. */
.short-figure {
    float: right;
    width: 200px;
    margin: 4px 0 16px 24px;
}
.short-tile {
    display: block;
    position: relative;
    width: 100%;
    aspect-ratio: 9 / 16;
    padding: 0;
    cursor: pointer;
    border: 1px solid var(--panel-edge);
    border-radius: 10px;
    overflow: hidden;
    background: #000;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.5);
    transition: transform 0.15s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}
.short-tile:hover {
    transform: translateY(-2px);
    border-color: var(--accent);
    box-shadow: 0 10px 24px rgba(0, 0, 0, 0.6);
}
.short-tile-thumb {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center;
}
.short-tile-play {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 15px 0 15px 25px;
    border-color: transparent transparent transparent #fff;
    filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.6));
    transition: transform 0.15s ease;
}
.short-tile:hover .short-tile-play { transform: translate(-50%, -50%) scale(1.12); }
.short-tile-tag {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 8px 9px;
    font-family: var(--font-body);
    font-size: 8.5pt;
    letter-spacing: 0.4px;
    color: #fff;
    text-align: center;
    background: linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0.82) 100%);
}
/* Grows modestly once the embed is playing, matching the StashPop behaviour. */
.short-figure.playing { width: 300px; }
.short-embed {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}
.short-caption {
    font-size: 8.5pt;
    font-style: italic;
    color: rgba(255, 255, 255, 0.6);
    text-align: center;
    padding: 8px 4px 0;
}
.short-caption a { color: var(--accent); }
.short-caption a:hover { color: #fff; }

@media (max-width: 640px) {
    .short-figure, .short-figure.playing {
        float: none;
        width: 220px;
        margin: 0 auto 18px auto;
    }
}

/* =====================  PROJECTS BENTO  ===================== */
.proj-bento {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 16px;
    margin: 14px 0 8px;
}
.proj-bento--featured { grid-template-columns: repeat(2, 1fr); }
.bento-section {
    grid-column: 1 / -1;
    font-family: var(--font-display);
    font-size: 12.5pt;
    letter-spacing: .03em;
    color: rgba(255, 255, 255, 0.88);
    margin: 16px 2px 2px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--panel-edge);
}
.bento-section:first-child { margin-top: 0; }

.ptile {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--panel-edge);
    border-radius: 14px;
    overflow: hidden;
    background: rgba(255, 255, 255, 0.045);
    text-decoration: none !important;
    color: #fff;
    transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}
.ptile:hover {
    transform: translateY(-3px);
    box-shadow: 0 16px 32px rgba(0, 0, 0, 0.42);
    border-color: color-mix(in srgb, var(--c) 60%, transparent);
}
.ptile-media { position: relative; height: 150px; overflow: hidden; display: grid; place-items: center; }
.ptile-photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* accent wash + bottom fade over the photo, and (for icon tiles) a darkener so
   the centered badge reads clearly against any photo */
.ptile-media::after {
    content: ""; position: absolute; inset: 0;
    background:
        linear-gradient(180deg, rgba(6, 8, 7, 0.15) 0%, transparent 35%, rgba(6, 8, 7, 0.6) 100%),
        linear-gradient(150deg, color-mix(in srgb, var(--c) 42%, transparent), transparent 62%);
}
.ptile-badge {
    position: relative; z-index: 1;
    display: grid; place-items: center;
    width: 78px; height: 78px; border-radius: 18px;
    background: rgba(6, 8, 7, 0.55);
    -webkit-backdrop-filter: blur(3px);
    backdrop-filter: blur(3px);
    border: 1px solid rgba(255, 255, 255, 0.22);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.4);
}
.ptile-badge img { width: 52px; height: 52px; object-fit: contain; }
.ptile-badge i { font-size: 30px; color: #fff; }
.ptile-body { padding: 13px 15px 16px; display: flex; flex-direction: column; gap: 3px; }
.ptile-kicker {
    font-size: 8.5pt; letter-spacing: .12em; text-transform: uppercase; font-weight: 600;
    color: color-mix(in srgb, var(--c) 72%, #fff);
}
.ptile-name { font-size: 14pt; font-weight: 700; line-height: 1.2; }
.ptile-tag { font-size: 10pt; color: rgba(255, 255, 255, 0.66); line-height: 1.35; }
.ptile-date { font-size: 8.5pt; color: rgba(255, 255, 255, 0.45); margin-top: 2px; }

/* =====================  HOME (project-first)  ===================== */
.home-sec-head {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 12px; margin: 24px 2px 4px;
}
.home-sec-title { font-size: 15pt; font-weight: 700; margin: 0; }
.home-see-all { font-size: 10.5pt; color: rgba(255, 255, 255, 0.8); text-decoration: none; white-space: nowrap; }
.home-see-all:hover { text-decoration: underline; }

/* Home-page coworker quote strip: one credible collaboration signal up front. */
.home-quote {
    margin: 26px 0 8px;
    padding: 22px 26px;
    border-radius: 14px;
    border: 1px solid var(--panel-edge);
    background:
        linear-gradient(180deg, var(--sheen) 0%, rgba(255,255,255,0) 55%),
        rgba(255, 255, 255, 0.04);
}
.home-quote-text {
    margin: 0 0 10px;
    font-size: 11pt;
    line-height: 1.5;
    color: var(--text-soft);
    font-style: italic;
}
.home-quote-meta { display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 10px; }
.home-quote-name { font-weight: 700; color: var(--accent); text-decoration: none; }
.home-quote-name:hover { text-decoration: underline; }
.home-quote-role { font-size: 10.5pt; color: rgba(255, 255, 255, 0.65); }
.home-quote-more { margin-left: auto; font-size: 10.5pt; color: rgba(255,255,255,0.8); text-decoration: none; white-space: nowrap; }
.home-quote-more:hover { text-decoration: underline; }
@media (max-width: 640px) { .home-quote-more { margin-left: 0; } }

.home-more {
    display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin: 22px 0 8px;
}
.home-more-card {
    display: flex; flex-direction: column; gap: 3px; padding: 13px 15px;
    border: 1px solid var(--panel-edge); border-radius: 12px;
    background: rgba(255, 255, 255, 0.04);
    text-decoration: none !important; color: #fff;
    transition: transform .15s ease, background .15s ease;
}
.home-more-card:hover { transform: translateY(-2px); background: rgba(255, 255, 255, 0.075); }
.hm-kicker { font-size: 8.5pt; letter-spacing: .12em; text-transform: uppercase; color: rgba(255, 255, 255, 0.55); font-weight: 600; }
.hm-title { font-size: 11pt; font-weight: 600; }

/* =====================  PROJECT DETAIL PAGE  =====================
   Open, editorial layout: no confining card. A masthead (large thumb + title),
   a readable text column, and screenshots that break out full width. */
.pdetail-back { margin: 4px 2px 16px; }
.pdetail-back a { font-size: 10.5pt; }

.pdetail-head { display: flex; gap: 20px; align-items: center; }
.pdetail-thumb {
    flex: 0 0 auto; width: 88px; height: 88px; border-radius: 20px;
    display: grid; place-items: center; overflow: hidden;
    background: linear-gradient(150deg, color-mix(in srgb, var(--c) 50%, transparent), rgba(10, 14, 12, 0.3));
    border: 1px solid color-mix(in srgb, var(--c) 45%, var(--panel-edge));
    box-shadow: 0 10px 26px rgba(0, 0, 0, 0.45);
}
.pdetail-thumb--photo img { width: 100%; height: 100%; object-fit: cover; }
.pdetail-thumb:not(.pdetail-thumb--photo) img { width: 58px; height: 58px; object-fit: contain; }
.pdetail-thumb i { font-size: 36px; color: #fff; }
.pdetail-headtext { flex: 1 1 auto; min-width: 0; }
.pdetail-name { font-family: var(--font-display); font-size: 30pt; font-weight: 700; margin: 0 0 3px; line-height: 1.02; }
.pdetail-sub { font-size: 10.5pt; color: rgba(255, 255, 255, 0.6); }
.pdetail-tag { font-size: 13pt; color: color-mix(in srgb, var(--c) 72%, #fff); margin-top: 4px; }
.pdetail-date { font-size: 10pt; color: rgba(255, 255, 255, 0.5); margin-top: 4px; }
.pdetail .item-tools { margin-top: 20px; }
.pdetail .item-actions { margin-top: 16px; }

.pdetail-body {
    margin-top: 24px; padding-top: 22px;
    border-top: 1px solid var(--panel-edge);
}
.pdetail-body p { font-size: 11.5pt; line-height: 1.72; color: rgba(255, 255, 255, 0.92); margin: 0 0 15px; }
.pdetail .demo-box { margin-top: 22px; }

/* Screenshot gallery: a responsive grid of tiles; click a tile to open it in
   the shared lightbox (lightbox.js). */
.pshots {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 18px; margin: 26px 0 8px;
}
.pshot { margin: 0; display: flex; flex-direction: column; }
.pshot-frame {
    position: relative; display: block; overflow: hidden; cursor: zoom-in;
    aspect-ratio: 16 / 10; border-radius: 12px;
    border: 1px solid var(--panel-edge); background: rgba(255, 255, 255, 0.03);
    box-shadow: 0 10px 26px rgba(0, 0, 0, 0.45);
}
.pshot-frame img {
    display: block; width: 100%; height: 100%;
    object-fit: cover; object-position: top center;
    transition: transform .45s cubic-bezier(.2, .7, .2, 1);
}
.pshot-frame:hover img, .pshot-frame:focus-visible img { transform: scale(1.06); }
.pshot-zoom {
    position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    color: #fff; opacity: 0; transition: opacity .3s ease;
    background: linear-gradient(0deg, rgba(0, 0, 0, .38), rgba(0, 0, 0, .04));
}
.pshot-frame:hover .pshot-zoom, .pshot-frame:focus-visible .pshot-zoom { opacity: 1; }
.pshot-zoom i {
    width: 46px; height: 46px; border-radius: 50%; font-size: 18px;
    display: flex; align-items: center; justify-content: center;
    background: rgba(0, 0, 0, .5); border: 1px solid rgba(255, 255, 255, .25);
}
.pshot-frame:focus-visible { outline: 2px solid var(--c); outline-offset: 2px; }
.pshot figcaption { margin-top: 9px; font-size: 9.5pt; color: rgba(255, 255, 255, 0.55); line-height: 1.45; }
@media (prefers-reduced-motion: reduce) {
    .pshot-frame img { transition: none; }
    .pshot-frame:hover img, .pshot-frame:focus-visible img { transform: none; }
}

/* Numbered how-to guide (e.g. opening the 3D map editor). */
.pguide {
    margin-top: 26px; padding: 20px 22px; border-radius: 12px;
    border: 1px solid var(--panel-edge); background: rgba(255, 255, 255, 0.03);
}
.pguide-title { font-family: var(--font-display); font-size: 15pt; font-weight: 700; margin: 0 0 4px; color: #fff; }
.pguide-intro { font-size: 10.5pt; color: rgba(255, 255, 255, 0.7); margin: 0 0 16px; }
.pguide-steps { list-style: none; counter-reset: step; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.pguide-steps li {
    counter-increment: step; position: relative; padding: 3px 0 3px 46px;
    font-size: 10.5pt; line-height: 1.6; color: rgba(255, 255, 255, 0.9);
}
.pguide-steps li::before {
    content: counter(step); position: absolute; left: 0; top: 1px;
    width: 30px; height: 30px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    font-size: 11pt; font-weight: 700; color: #fff;
    background: color-mix(in srgb, var(--c) 45%, transparent);
    border: 1px solid color-mix(in srgb, var(--c) 70%, #fff);
}
.pguide-steps li a { color: color-mix(in srgb, var(--c) 72%, #fff); }
.pguide-steps strong { color: #fff; font-weight: 600; }

/* Predecessor note: a distinct, dashed sub-card under the demo. */
.pred {
    margin-top: 28px; padding: 18px 20px 20px; border-radius: 12px;
    border: 1px dashed color-mix(in srgb, var(--c) 40%, var(--panel-edge));
    background: rgba(255, 255, 255, 0.03);
}
.pred-kicker { font-size: 8.5pt; letter-spacing: .14em; text-transform: uppercase; color: color-mix(in srgb, var(--c) 65%, #fff); font-weight: 600; }
.pred-name { font-family: var(--font-display); font-size: 16pt; font-weight: 700; margin: 3px 0 0; color: #fff; }
.pred-tag { font-size: 10pt; color: rgba(255, 255, 255, 0.6); margin-bottom: 6px; }
.pred-media { display: block; width: 100%; max-width: 460px; height: auto; border-radius: 10px; border: 1px solid var(--panel-edge); margin: 12px 0; }
.pred-body p { font-size: 10.5pt; line-height: 1.62; color: rgba(255, 255, 255, 0.82); margin: 0 0 10px; }
.pred .item-actions { margin-top: 4px; }

@media (max-width: 760px) {
    .proj-bento, .proj-bento--featured { grid-template-columns: 1fr; }
    .home-more { grid-template-columns: 1fr 1fr; }
    .pdetail-head { flex-direction: column; align-items: flex-start; gap: 14px; }
    .pdetail-name { font-size: 25pt; }
}

/* =====================  STATIC COWORKER TESTIMONIALS (Work History)  ===== */
.work-testimonials { margin-top: 18px; }
.wt-kicker {
    font-size: 9pt; letter-spacing: .14em; text-transform: uppercase;
    color: var(--accent); font-weight: 600; margin-bottom: 10px;
}
.wt-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
.wt-card {
    margin: 0; display: flex; flex-direction: column; align-items: center; text-align: center;
    padding: 16px 15px 17px; border: 1px solid var(--panel-edge); border-radius: 12px;
    background: rgba(0, 0, 0, 0.20);
}
.wt-photo {
    width: 58px; height: 58px; border-radius: 50%; object-fit: cover;
    border: 2px solid var(--accent); margin-bottom: 11px;
}
.wt-quote { font-size: 9.5pt; line-height: 1.55; color: rgba(255, 255, 255, 0.82); margin: 0 0 11px; }
.wt-meta { display: flex; flex-direction: column; gap: 1px; }
.wt-name { font-size: 10.5pt; font-weight: 600; color: #fff; text-decoration: none; }
.wt-name:hover { color: var(--accent); }
.wt-role { font-size: 8.5pt; color: rgba(255, 255, 255, 0.55); }

/* =====================  HOME CONTACT BOX  ===================== */
.home-contact {
    margin-top: 26px; padding: 24px 22px 26px; text-align: center;
    border: 1px solid var(--panel-edge); border-radius: 14px;
    background: linear-gradient(180deg, var(--sheen) 0%, rgba(255, 255, 255, 0) 60%), var(--panel);
}
.home-contact-kicker { font-family: var(--font-display); font-size: 17pt; color: #fff; margin-bottom: 6px; }
.home-contact-lead { font-size: 11pt; color: rgba(255, 255, 255, 0.8); max-width: 620px; margin: 0 auto 16px; line-height: 1.55; }
.home-contact-cta { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }

/* =====================  SKILLS BENTO (colour-coded by category)  ========= */
.skill-group { margin-top: 24px; }
.skill-group-title {
    font-family: var(--font-display); font-size: 15pt; color: var(--c);
    margin: 0 0 12px; padding-bottom: 6px;
    border-bottom: 1px solid color-mix(in srgb, var(--c) 45%, var(--panel-edge));
}
.skill-bento { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 14px; align-items: start; }
.skill-tile {
    border: 1px solid var(--panel-edge); border-top: 3px solid var(--c); border-radius: 12px;
    padding: 14px 16px 15px;
    background: linear-gradient(180deg, var(--sheen) 0%, rgba(255, 255, 255, 0) 55%), var(--panel);
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.35);
}
.skill-tile-head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.skill-ico {
    flex: 0 0 auto; width: 36px; height: 36px; border-radius: 9px; display: grid; place-items: center;
    background: color-mix(in srgb, var(--c) 22%, transparent);
    border: 1px solid color-mix(in srgb, var(--c) 40%, transparent);
}
.skill-ico img { width: 20px; height: 20px; object-fit: contain; }
.skill-ico i { font-size: 16px; color: color-mix(in srgb, var(--c) 78%, #fff); }
.skill-tile-name { font-size: 12.5pt; font-weight: 700; margin: 0; color: #fff; }
.skill-tile-desc p { font-size: 10pt; line-height: 1.5; color: rgba(255, 255, 255, 0.78); margin: 0 0 6px; }
.skill-tile-desc p:last-child { margin-bottom: 0; }
.skill-tile-desc a { color: color-mix(in srgb, var(--c) 70%, #fff); }
.skill-pills { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.skill-pill {
    display: inline-flex; align-items: center; font-size: 8.5pt; font-weight: 600;
    letter-spacing: .01em; line-height: 1; padding: 6px 11px; border-radius: 999px;
    color: color-mix(in srgb, var(--c) 82%, #fff); text-decoration: none;
    background: color-mix(in srgb, var(--c) 16%, transparent);
    border: 1px solid color-mix(in srgb, var(--c) 38%, transparent);
    transition: background .2s ease, border-color .2s ease, transform .2s ease;
}
.skill-pill:hover, .skill-pill:focus-visible {
    background: color-mix(in srgb, var(--c) 30%, transparent);
    border-color: color-mix(in srgb, var(--c) 60%, transparent);
    color: #fff; transform: translateY(-1px);
}

@media (max-width: 760px) {
    .wt-grid { grid-template-columns: 1fr; }
    .skill-bento { grid-template-columns: 1fr; }
}

/* =====================  GLOBAL RESPONSIVE  =====================
   Cross-cutting breakpoints. Kept last so they override the base rules
   defined across base/layout/components/pages above. */
/* Tablet / small-laptop: keep the header on one line but let it breathe. */
@media (max-width: 800px) {
    #header { height: auto; }
    #header #title #name { font-size: 38pt; }
}

/* Phones: stack the header, centre it, and shrink the oversized type. */
@media (max-width: 600px) {
    #header {
        height: auto;
        text-align: center;
    }
    #header #title,
    #header #location {
        float: none;
        display: block;
        padding: 8px 0;
        line-height: 1.25;
    }
    /* The header centres here, so the left accent rule has nothing to align to
       and would just hang off the side of centred text. */
    #header #title { margin-left: 0; }
    #header #title::before { display: none; }
    #header #title #name { font-size: 30pt; }
    #header #title #subheader { font-size: 14pt; text-align: center; }
    #header #location { font-size: 12pt; text-align: center; }
    #social-bubbles { justify-content: center; }

    /* Media-left cards (Projects, AI) stack on phones so a wide gif or tall
       video does not crush the text into a thin column beside it. */
    .hcard-projects, .hcard-ai { flex-direction: column; }
    .hcard-projects .hcard-side-media { width: 100%; height: auto; }
    .hcard-ai .hcard-side-media {
        align-self: flex-start;
        width: auto;
        height: 240px;
        min-height: 0;
    }

    /* Tab bar: tighter, wraps onto multiple lines instead of overflowing. */
    #body .title {
        font-size: 13pt;
        margin-right: 5px;
        margin-bottom: 5px;
        padding: 5px 9px;
    }

    /* The "+" group is a single inline-grid item, so the nav treats it as one
       unbreakable block: it drops to its own line whole and the three pills sit
       stranded together instead of flowing with the rest. Once open, dissolve
       both wrappers with display:contents, which makes the pills direct
       children of #tabs so they wrap individually like every other pill. The
       plus has done its job by then, so it goes rather than sitting invisible
       in the flow. The pills still fade and stagger in; what is lost here is
       only the plus expanding over them, which needs the grid to stack. */
    #body .more-group.is-open,
    #body .more-group.is-open .more-pills { display: contents; }
    #body .more-group.is-open .tab-more { display: none; }
    /* Re-match the tighter phone metrics, which the open-state rules in
       layout.css outrank on specificity. */
    #body .more-group.is-open .more-pills .title {
        margin-right: 5px;
        padding-left: 9px;
        padding-right: 9px;
    }

    /* Panels and headings scale down so nothing clips the edges. */
    .bio, .policy, .landing, .tab-pane { padding: 14px 4px 10px 4px; }
    .bio-panel { padding: 16px 16px; }
    .bio-heading { font-size: 20pt; }
    .bio-body { font-size: 11.5pt; }

    /* Data / skill cards sit flush to the narrow viewport. */
    .item { margin: 8px 0; }
    .section-title { margin: 18px 0 8px 0; }

    .page-header { margin: 4px 0 18px 0; padding-left: 12px; }
    .page-title { font-size: 22pt; }
    .page-intro { font-size: 11pt; }

    .key-skills { margin: 10px 0 14px 0; }

    .form-actions { flex-wrap: wrap; }
}

/* Very small phones. */
@media (max-width: 380px) {
    #header #title #name { font-size: 24pt; }
    #header #title #subheader { font-size: 12pt; }
    #body .title { font-size: 11pt; padding: 4px 7px; }
}
