/* ==========================================================================
   Vanessa Gomez — portfolio (light-first bento theme)
   Background grid + card surfaces, one accent color (5 selectable hues).
   Type: IBM Plex Sans (text + headings) + IBM Plex Mono (technical metadata only).
   Light palette is the default; dark follows the visitor's OS preference.
   ========================================================================== */

:root {
    --bg: #FAF8F4;
    --grid-line: rgba(30, 26, 18, 0.05);
    --surface: #FFFFFF;
    --surface-2: #F2EFE8;
    --line: #E1DDD3;
    --ink: #1D1E20;
    --muted: #5A5D61;
    --field-dot: rgba(20, 18, 12, 0.09);
    --shadow-hover: 0 10px 26px rgba(20, 18, 12, 0.08);

    --font-sans: 'IBM Plex Sans', -apple-system, 'Segoe UI', sans-serif;
    --font-mono: 'IBM Plex Mono', 'SFMono-Regular', Consolas, monospace;

    --container: min(1560px, 94vw);
    --radius: 14px;
}

@media (prefers-color-scheme: dark) {
    :root {
        --bg: #0D0F10;
        --grid-line: rgba(255, 255, 255, 0.045);
        --surface: #16191B;
        --surface-2: #1D2124;
        --line: #282D30;
        --ink: #E9ECEC;
        --muted: #9AA3A7;
        --field-dot: rgba(255, 255, 255, 0.07);
        --shadow-hover: 0 10px 30px rgba(0, 0, 0, 0.45);
    }
}

*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
    font-family: var(--font-sans);
    font-size: 1rem;
    line-height: 1.6;
    color: var(--ink);
    background-color: var(--bg);
    /* the signature grid backdrop */
    background-image:
        linear-gradient(var(--grid-line) 1px, transparent 1px),
        linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
    background-size: 88px 88px;
    -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }

.container {
    max-width: var(--container);
    margin: 0 auto;
    padding: 28px 24px 40px;
}

/* ---------- accessibility ---------- */

.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    background: var(--accent);
    color: #06211E;
    padding: 10px 18px;
    z-index: 200;
    border-radius: 0 0 var(--radius) 0;
    font-weight: 600;
}

.skip-link:focus { left: 0; }

a:focus-visible, button:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
    border-radius: 4px;
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }
}

/* ---------- typography ---------- */

h1, h2, h3 { line-height: 1.22; font-weight: 700; letter-spacing: -0.015em; color: var(--ink); }
h1 { font-size: clamp(2.1rem, 4.5vw, 2.9rem); }
h2 { font-size: clamp(1.32rem, 1.6vw, 1.55rem); margin-bottom: 0.6rem; }
h3 { font-size: 1.08rem; }

body { font-size: 1rem; line-height: 1.65; }

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }

.muted  { color: var(--muted); }
.small  { font-size: 0.9rem; }
.mono   { font-family: var(--font-mono); }
strong  { color: var(--ink); font-weight: 700; }

p { line-height: 1.65; }
.card p, .entry p, .p-body p { max-width: 58ch; }

.eyebrow {
    font-family: var(--font-sans);
    font-weight: 600;
    font-size: 0.85rem;
    letter-spacing: 0.01em;
    color: var(--muted);
    margin-bottom: 0.5rem;
}

.label {
    font-family: var(--font-sans);
    font-weight: 600;
    font-size: 0.82rem;
    letter-spacing: 0.01em;
    color: var(--muted);
    margin: 1.2rem 0 0.5rem;
    display: flex;
    align-items: center;
    gap: 8px;
}

.card > .label:first-child { margin-top: 0; }

/* ---------- bento grid ---------- */

.bento {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 20px;
    align-items: stretch;
}

.card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 30px;
    min-width: 0;
}

/* grid placement (desktop) */
.card-hero       { grid-column: 1 / 3; }
.card-about      { grid-column: 3 / 4; grid-row: 1 / 3; }
.card-contact    { grid-column: 1 / 2; grid-row: 2 / 4; }
.card-time       { grid-column: 2 / 3; }
.card-experience { grid-column: 2 / 3; }
.card-now        { grid-column: 3 / 4; }
.card-projects   { grid-column: 1 / 2; }
.card-guestbook  { grid-column: 2 / 3; }
.card-resume     { grid-column: 3 / 4; }
.card-education  { grid-column: 1 / 2; }
.card-theme      { grid-column: 2 / 3; }
.card-footer     { grid-column: 3 / 4; display: flex; flex-direction: column; justify-content: space-between; gap: 12px; }

/* ---------- hero card ---------- */

.card-hero {
    display: grid;
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
    gap: 28px;
    align-items: center;
    padding: 34px;
}

.hero-lede { font-size: clamp(1.4rem, 2vw, 1.7rem); font-weight: 500; line-height: 1.4; margin-bottom: 1rem; }
.hero-copy .muted { margin-bottom: 0.8rem; max-width: 54ch; }

.hero-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    margin-top: 1.4rem;
}

.btn {
    display: inline-block;
    padding: 12px 22px;
    border-radius: 10px;
    font-weight: 500;
    border: 1px solid transparent;
}

.btn:hover { text-decoration: none; }

.btn-primary {
    background: var(--accent);
    color: #06211E;
}

.btn-primary:hover { filter: brightness(1.1); }

.icon-btn {
    width: 46px;
    height: 46px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--line);
    border-radius: 10px;
    color: var(--ink);
    background: var(--surface-2);
    transition: border-color 0.2s ease, color 0.2s ease;
}

.icon-btn:hover { border-color: var(--accent); color: var(--accent); }
.icon-btn svg { width: 20px; height: 20px; }

.hero-photo { justify-self: end; width: min(280px, 100%); }

.photo-placeholder,
.hero-photo img {
    aspect-ratio: 1;
    width: 100%;
    border-radius: var(--radius);
    object-fit: cover;
}

.photo-placeholder {
    background: var(--surface-2);
    border: 1px solid var(--line);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--muted);
    font-size: 3rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    user-select: none;
}

/* ---------- about card ---------- */

.card-about .tags { margin-top: 2px; }
.about-extra { margin-top: 1.1rem; }

.tags {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.tags li {
    font-family: var(--font-mono);
    font-size: 0.78rem;
    color: var(--muted);
    border: 1px solid var(--line);
    border-radius: 999px;
    padding: 5px 12px;
    background: var(--surface-2);
}

/* ---------- contact card ---------- */

.link-list { list-style: none; display: grid; gap: 6px; }
.link-list.row { display: flex; flex-wrap: wrap; gap: 14px; }

.interest-box {
    margin-top: 22px;
    padding: 16px 18px;
    background: var(--surface-2);
    border: 1px solid var(--line);
    border-radius: 10px;
}

.interest-box .label { margin-top: 0; }
.interest-box .mini-list { gap: 8px; }

/* ---------- time card ---------- */

.clock {
    font-size: clamp(2.2rem, 4vw, 2.9rem);
    font-weight: 600;
    letter-spacing: -0.02em;
    line-height: 1.1;
}

.clock-secondary { font-size: clamp(1.7rem, 3vw, 2.2rem); color: var(--muted); }

.time-divider {
    border-top: 1px dashed var(--line);
    margin: 16px 0 4px;
    padding-top: 2px;
}

/* ---------- link cards ---------- */

.card-link {
    display: flex;
    flex-direction: column;
    gap: 10px;
    color: var(--ink);
    transition: border-color 0.2s ease, background 0.2s ease;
}

.card-link:hover {
    text-decoration: none;
    border-color: var(--accent);
    background: var(--surface-2);
}

.card-link-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
}

.arrow {
    font-size: 1.1rem;
    color: var(--muted);
    transition: transform 0.2s ease, color 0.2s ease;
}

.card-link:hover .arrow {
    color: var(--accent);
    transform: translate(3px, -3px);
}

.mini-list { list-style: none; display: grid; gap: 7px; font-size: 0.92rem; color: var(--muted); line-height: 1.5; }

/* ---------- subpages (guestbook / projects / experience) ---------- */

.page {
    width: min(1680px, 94vw);
    margin-inline: auto;
}

.back-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--muted);
    border: 1px solid var(--line);
    background: var(--surface);
    border-radius: 10px;
    padding: 9px 16px;
    font-size: 0.92rem;
    margin-bottom: 44px;
}

.back-btn:hover { color: var(--ink); border-color: var(--accent); text-decoration: none; }

.page-head { text-align: center; margin-bottom: 40px; }
.page-head h1 { margin-bottom: 0.5rem; }
.page-head p { color: var(--muted); }

/* ----- guestbook ----- */

.gb-compose {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    margin-bottom: 40px;
    overflow: hidden;
}

.gb-compose-toggle {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    background: none;
    border: none;
    color: var(--ink);
    font: inherit;
    font-weight: 500;
    padding: 20px 24px;
    cursor: pointer;
}

.gb-compose-toggle .plus { color: var(--muted); font-size: 1.3rem; line-height: 1; transition: transform 0.2s ease; }
.gb-compose-toggle[aria-expanded="true"] .plus { transform: rotate(45deg); }

.gb-form { padding: 0 24px 24px; display: grid; gap: 14px; }
.gb-form[hidden] { display: none; }

.gb-form label { font-size: 0.85rem; color: var(--muted); display: grid; gap: 6px; }

.gb-form input,
.gb-form textarea {
    font: inherit;
    color: var(--ink);
    background: var(--surface-2);
    border: 1px solid var(--line);
    border-radius: 10px;
    padding: 11px 14px;
    width: 100%;
}

.gb-form input:focus,
.gb-form textarea:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: transparent; }

.gb-form textarea { resize: vertical; min-height: 90px; }

.gb-form .btn { justify-self: start; cursor: pointer; border: none; font: inherit; }

.gb-status { font-size: 0.9rem; color: var(--muted); min-height: 1.2em; }
.gb-status.error { color: #E5766B; }
.gb-status.ok { color: var(--accent); }

.gb-count { font-weight: 600; margin-bottom: 18px; }

.gb-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 18px;
    align-items: start;
}

.gb-card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 20px 22px;
}

.gb-msg { margin-bottom: 14px; overflow-wrap: anywhere; }

.gb-meta {
    display: flex;
    align-items: center;
    gap: 10px;
    border-top: 1px solid var(--line);
    padding-top: 14px;
    font-size: 0.92rem;
}

.gb-avatar {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    font-weight: 600;
    font-size: 0.9rem;
    flex-shrink: 0;
}

.gb-name { font-weight: 600; }
.gb-time { color: var(--muted); }

.gb-like {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: none;
    border: none;
    color: var(--muted);
    font: inherit;
    font-size: 0.92rem;
    cursor: pointer;
    padding: 4px 6px;
    border-radius: 8px;
}

.gb-like:hover { color: var(--accent); background: var(--accent-dim); }
.gb-like.liked { color: var(--accent); }
.gb-like svg { width: 16px; height: 16px; }

.gb-notice {
    background: var(--surface);
    border: 1px dashed var(--line);
    border-radius: var(--radius);
    padding: 26px;
    color: var(--muted);
    text-align: center;
}

/* ----- projects / experience pages ----- */

    /* ----- experience page section headings ----- */

body[data-page="experience"] .section-label {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 20px;

    margin: 64px 0 30px;

    color: var(--ink);
    font-family: var(--font-sans);
    font-size: clamp(1.3rem, 1.8vw, 1.6rem);
    font-weight: 700;
    letter-spacing: -0.01em;
    line-height: 1;
    text-align: center;
    text-transform: capitalize;
}

/* Horizontal separator lines beside each title */
body[data-page="experience"] .section-label::before,
body[data-page="experience"] .section-label::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--line);
}

/* Keeps the first Experience heading closer to the page header */
body[data-page="experience"] .page-head + .section-label {
    margin-top: 0;
}

/* Adds more separation before Research and Education */
body[data-page="experience"] .stack + .section-label {
    margin-top: 78px;
}

@media (max-width: 700px) {
    body[data-page="experience"] .section-label {
        gap: 12px;
        margin-bottom: 24px;
        font-size: 1rem;
    }

    body[data-page="experience"] .stack + .section-label {
        margin-top: 56px;
    }
}

.stack {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 18px;
    width: 100%;
    align-items: stretch;
}

.p-card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    overflow: hidden;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.p-thumb {
    aspect-ratio: 16 / 8;
    background: var(--surface-2);
    border-bottom: 1px solid var(--line);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

.p-thumb span {
    font-family: var(--font-mono);
    font-size: 0.8rem;
    color: var(--muted);
}

.p-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: top;
}

.p-body {
    padding: 22px 24px 24px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    flex: 1;
}

.p-body p {
    color: var(--muted);
}

.p-links {
    display: flex;
    gap: 18px;
    font-weight: 500;
    margin-top: auto;
}

.p-links:empty {
    display: none;
}

@media (max-width: 1250px) {
    .stack {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 700px) {
    .stack {
        grid-template-columns: 1fr;
    }
}

/* ----- experience / education entries ----- */

.entry {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 26px 28px;
    min-width: 0;
}

.entry h2 { margin-top: 0.3rem; }

.entry-org {
    color: var(--ink);
    font-weight: 500;
    margin-bottom: 1rem;
}

.entry ul:not(.tags) {
    list-style: none;
    display: grid;
    gap: 10px;
    margin-bottom: 14px;
    color: var(--muted);
    line-height: 1.6;
}

.entry ul:not(.tags) li { position: relative; padding-left: 18px; }

.entry ul:not(.tags) li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.62em;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--line);
}

.metric { color: var(--accent); font-weight: 600; }

/* ---------- responsive ---------- */

@media (max-width: 980px) {
    .bento { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .card-hero       { grid-column: 1 / 3; }
    .card-about      { grid-column: 1 / 3; grid-row: auto; }
    .card-contact    { grid-column: 1 / 2; grid-row: auto; }
    .card-time       { grid-column: 2 / 3; }
    .card-experience { grid-column: 1 / 2; }
    .card-now        { grid-column: 2 / 3; }
    .card-projects   { grid-column: 1 / 2; }
    .card-guestbook  { grid-column: 2 / 3; }
    .card-resume     { grid-column: 1 / 2; }
    .card-education  { grid-column: 2 / 3; }
    .card-theme      { grid-column: 1 / 2; }
    .card-footer     { grid-column: 2 / 3; }
}

@media (max-width: 640px) {
    .bento { grid-template-columns: 1fr; }
    .bento > .card, .bento > .card-link { grid-column: 1 / 2 !important; grid-row: auto !important; }

    .card-hero { grid-template-columns: 1fr; padding: 26px; }
    .hero-photo { justify-self: start; width: min(220px, 70%); order: -1; }

    .gb-grid { grid-template-columns: 1fr; }
    .card-footer { flex-direction: column; align-items: flex-start; }
}

/* ==========================================================================
   EFFECTS LAYER — themes, hover glow, loader, motion
   ========================================================================== */

/* ---------- accent themes (picked via the dots card, persisted) ---------- */

:root, [data-theme="teal"] {
    --accent: #0E7C6B;
    --accent-dim: rgba(14, 124, 107, 0.12);
}

[data-theme="red"] {
    --accent: #A32E63;
    --accent-dim: rgba(163, 46, 99, 0.12);
}

[data-theme="amber"] {
    --accent: #A8600A;
    --accent-dim: rgba(168, 96, 10, 0.12);
}

[data-theme="blue"] {
    --accent: #1D66C4;
    --accent-dim: rgba(29, 102, 196, 0.12);
}

[data-theme="purple"] {
    --accent: #6E3FC9;
    --accent-dim: rgba(110, 63, 201, 0.13);
}

/* dark mode gets the richer, more saturated hues that read well on a dark surface */
@media (prefers-color-scheme: dark) {
    :root, [data-theme="teal"] {
        --accent: #2FBFAF;
        --accent-dim: rgba(47, 191, 175, 0.14);
    }
    [data-theme="red"] {
        --accent: #c10378;
        --accent-dim: rgba(224, 82, 191, 0.14);
    }
    [data-theme="amber"] {
        --accent: #ec7803;
        --accent-dim: rgba(224, 155, 58, 0.14);
    }
    [data-theme="blue"] {
        --accent: #2d99f7;
        --accent-dim: rgba(76, 188, 240, 0.16);
    }
    [data-theme="purple"] {
        --accent: #9f62f3;
        --accent-dim: rgba(155, 99, 232, 0.16);
    }
}

/* ---------- theme picker card ---------- */

.card-theme {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
}

.theme-dot {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: none;
    cursor: pointer;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.theme-dot:hover { transform: scale(1.12); }

.theme-dot.active {
    box-shadow: 0 0 0 3px var(--bg), 0 0 0 6px var(--ink);
}

.theme-dot[data-theme="teal"]   { background: #2FBFAF; }
.theme-dot[data-theme="red"]    { background: #c10378; }
.theme-dot[data-theme="amber"]  { background: #ec7803; }
.theme-dot[data-theme="blue"]   { background: #2d99f7; }
.theme-dot[data-theme="purple"] { background: #9f62f3; }

/* ---------- hover feedback (all cards, every page) ---------- */
/* restrained: a border-color shift plus a soft neutral lift, no accent-colored blur */

.card, .card-link, .gb-card, .p-card, .entry, .gb-compose, .back-btn {
    transition: border-color 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
}

.card:hover,
.card-link:hover,
.gb-card:hover,
.p-card:hover,
.entry:hover,
.gb-compose:focus-within,
.back-btn:hover {
    border-color: var(--accent);
    box-shadow: var(--shadow-hover);
}

/* ---------- full-screen loading screen ---------- */

.loader {
    position: fixed;
    inset: 0;
    z-index: 999;
    background-color: var(--bg);
    background-image:
        linear-gradient(var(--grid-line) 1px, transparent 1px),
        linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
    background-size: 88px 88px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    overflow: hidden;
    opacity: 1;
    transition: opacity 0.55s ease;
}

.loader-out { opacity: 0; pointer-events: none; }

.loader-glow {
    position: absolute;
    top: 0;
    left: 0;
    width: 520px;
    height: 520px;
    border-radius: 50%;
    background: radial-gradient(circle, var(--accent-dim), transparent 65%);
    transform: translate(-9999px, -9999px);
    pointer-events: none;
    will-change: transform;
}

.loader-center { text-align: center; position: relative; }

.loader-mark {
    font-family: var(--font-mono);
    font-size: 1rem;
    letter-spacing: 0.3em;
    color: var(--accent);
    margin-bottom: 10px;
}

.loader-count {
    font-size: clamp(3.6rem, 10vw, 6rem);
    font-weight: 600;
    letter-spacing: -0.03em;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

.loader-label {
    margin-top: 12px;
    font-size: 0.85rem;
    color: var(--muted);
}

.loader-skip {
    position: absolute;
    bottom: 28px;
    left: 50%;
    transform: translateX(-50%);
    font-size: 0.75rem;
    color: var(--muted);
    opacity: 0.7;
}

/* hide page content under the loader to avoid a flash */
body.loading { overflow: hidden; }

/* ---------- entrance stagger ---------- */

.bento > *, .page > * {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 0.5s ease, transform 0.5s ease;
}

body.loaded .bento > *,
body.loaded .page > * {
    opacity: 1;
    transform: none;
}

/* no-JS / reduced-motion fallback: content always visible */
@media (prefers-reduced-motion: reduce) {
    .bento > *, .page > * { opacity: 1; transform: none; }
}


/* ---------- footer sound toggle ---------- */

.sound-toggle {
    font-family: var(--font-mono);
    font-size: 0.8rem;
    color: var(--muted);
    background: var(--surface-2);
    border: 1px solid var(--line);
    border-radius: 8px;
    padding: 6px 12px;
    cursor: pointer;
}

.sound-toggle:hover { color: var(--accent); border-color: var(--accent); }

/* ---------- wide-screen breathing room ---------- */
@media (min-width: 1500px) {
    .bento { gap: 24px; }
    .card { padding: 34px; }
    .card-hero { padding: 44px; }
}

/* ==========================================================================
   EMBEDDED MONITOR MODE — active only when portfolio.html is running inside
   the room intro's monitor iframe (html.vg-embedded, set by effects.js via
   `window.self !== window.top`). The monitor screen is a small viewport, so
   this tightens spacing and type scale to read as a miniature desktop app
   rather than a shrunk full-size page. Standalone visits are untouched —
   nothing here applies outside the iframe. Bento layout/grid areas and the
   responsive breakpoints above are unchanged, just denser.
   ========================================================================== */
html.vg-embedded {
    --radius: 10px;
}

html.vg-embedded body {
    font-size: 0.9rem;
}

html.vg-embedded .container {
    padding: 16px 14px 22px;
}

html.vg-embedded .bento {
    gap: 12px;
}

html.vg-embedded .card {
    padding: 18px;
}

html.vg-embedded .card-hero {
    gap: 18px;
    padding: 20px;
}

html.vg-embedded h1 { font-size: clamp(1.4rem, 3.4vw, 1.8rem); }
html.vg-embedded h2 { font-size: 1.05rem; margin-bottom: 0.45rem; }
html.vg-embedded .hero-lede { font-size: clamp(1.15rem, 2.2vw, 1.35rem); }
html.vg-embedded .label { margin: 0.9rem 0 0.4rem; }
html.vg-embedded .card > .label:first-child { margin-top: 0; }

/* ==========================================================================
   INTERACTIVE ROOM INTRO — full-viewport cinematic lead-in that lives in
   index.html only. The bento portfolio itself lives in portfolio.html and
   is embedded inside the monitor screen via iframe once powered on. See
   room-intro.js for the state machine, hotspot math, and gesture handling.
   ========================================================================== */

body.intro-locked { overflow: hidden; overscroll-behavior: none; }

.room-intro {
    position: fixed;
    inset: 0;
    z-index: 500;
    background: #0B0A08;
    overflow: hidden;
}

.ri-loading {
    position: absolute;
    inset: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #0B0A08;
    color: #C9C2B4;
    font-size: 0.85rem;
    letter-spacing: 0.08em;
    transition: opacity 0.4s ease;
}

.ri-loading[hidden] { display: none; }

.ri-stage {
    position: relative;
    width: 100%;
    height: 100%;
}

/* full-viewport stage: every layer covers the whole browser window, no
   letterboxing. object-position is set per shot (via --ox/--oy custom
   properties from room-intro.js) so the door/desk/monitor stays framed
   as the crop changes with viewport aspect ratio. */
.ri-frame {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: hidden;
    touch-action: none;
}

.ri-layer {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: var(--ox, 50%) var(--oy, 50%);
    opacity: 0;
    pointer-events: none;
    z-index: 1;
    transition: opacity 0.65s ease;
    image-rendering: pixelated;
}

.ri-layer--active { opacity: 1; z-index: 2; }

.ri-layer--push { transform: scale(1.055); transition: opacity 0.65s ease, transform 0.9s cubic-bezier(0.22, 1, 0.36, 1); }

/* transparent hit areas — room-intro.js computes each one's on-screen px
   rect from the object-fit:cover math (image scale + crop offset) and
   writes it as inline left/top/width/height, recalculated on resize so
   alignment survives the crop at any viewport size */
.ri-hotspot {
    position: absolute;
    min-width: 44px;
    min-height: 44px;
    background: transparent;
    border: none;
    padding: 0;
    margin: 0;
    cursor: pointer;
    display: none;
    z-index: 5;
}

.ri-hotspot.is-active { display: block; }

.ri-hotspot::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 10px;
    background: radial-gradient(ellipse at center, var(--accent-dim), transparent 70%);
    opacity: 0;
    transition: opacity 0.2s ease, transform 0.2s ease;
    transform: scale(0.98);
}

.ri-hotspot:hover::after,
.ri-hotspot:focus-visible::after {
    opacity: 1;
    transform: scale(1);
}

.ri-hotspot:focus-visible { outline: none; }
.ri-hotspot:focus-visible::after { box-shadow: 0 0 0 2px var(--accent) inset; }

/* debug mode (?debug=1) — outlines the currently active hotspot and the
   monitor screen-embed rect against the new cover-cropped artwork */
.room-intro.debug .ri-hotspot.is-active::after {
    opacity: 1;
    outline: 2px dashed #FF2D55;
    background: rgba(255, 45, 85, 0.12);
}
.room-intro.debug .ri-screen-embed { outline: 2px dashed #2FBFAF; }

/* persistent, subtle instruction text — content set per state by
   room-intro.js; hidden on states with no user action of their own
   (the automatic bedroom→desk push, and once the portfolio is live) */
.ri-hint {
    position: absolute;
    left: 50%;
    bottom: max(26px, 6vh);
    transform: translate(-50%, 4px);
    z-index: 8;
    background: rgba(13, 15, 16, 0.74);
    color: #F4F1EA;
    font-family: var(--font-mono);
    font-size: 0.78rem;
    letter-spacing: 0.03em;
    padding: 8px 16px;
    border-radius: 999px;
    opacity: 0;
    pointer-events: none;
    white-space: nowrap;
    transition: opacity 0.3s ease, transform 0.3s ease;
}

.ri-hint.is-visible { opacity: 1; transform: translate(-50%, 0); }

/* back button — one step back per press; hidden on the very first scene */
.ri-back {
    position: absolute;
    top: max(18px, env(safe-area-inset-top, 0px));
    left: max(18px, env(safe-area-inset-left, 0px));
    z-index: 9;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 44px;
    background: rgba(13, 15, 16, 0.6);
    color: #F4F1EA;
    border: 1px solid rgba(244, 241, 234, 0.28);
    border-radius: 999px;
    padding: 8px 16px 8px 12px;
    font-family: var(--font-mono);
    font-size: 0.78rem;
    letter-spacing: 0.02em;
    cursor: pointer;
    opacity: 0;
    transform: translateY(-4px);
    transition: opacity 0.3s ease, transform 0.3s ease, background-color 0.2s ease;
    pointer-events: none;
}

.ri-back.is-visible { opacity: 1; transform: translateY(0); pointer-events: auto; }
.ri-back:hover { background: rgba(13, 15, 16, 0.82); }
.ri-back:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ri-back svg { width: 14px; height: 14px; flex: none; }

/* monitor screen embed — clipped exactly to the black screen rect measured
   from MasterMonitor.png; the bezel/desk/keyboard/phone stay visible around
   it because this only covers that inner rect, not the whole frame */
.ri-screen-embed {
    position: absolute;
    z-index: 4;
    overflow: hidden;
    border-radius: clamp(4px, 1.1vw, 14px);
    background: #000;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.5s ease, box-shadow 0.5s ease;
}

.ri-screen-embed.is-glow { box-shadow: 0 0 44px 12px var(--accent-dim); }
.ri-screen-embed.is-on { opacity: 1; pointer-events: auto; }

.ri-screen-frame {
    display: block;
    width: 100%;
    height: 100%;
    border: 0;
    background: #fff;
}

/* hides the embedded portfolio's own scrollbar chrome only when it is
   actually running inside the monitor iframe (see effects.js) — scrolling
   itself still works, just without the visual scrollbar */
html.vg-embedded { scrollbar-width: none; }
html.vg-embedded::-webkit-scrollbar { display: none; width: 0; height: 0; }

@media (prefers-reduced-motion: reduce) {
    .ri-layer { transition: opacity 0.22s ease; }
    .ri-layer--push { transform: none; transition: opacity 0.22s ease; }
    .ri-hint, .ri-back, .ri-screen-embed { transition: opacity 0.15s ease; }
}

/* ---------- ambient card graphics (data-anim fields) ---------- */

.anim-field {
    margin-top: auto;
    display: grid;
    grid-template-columns: repeat(var(--cols, 16), 1fr);
    gap: 7px;
    padding: 4px 2px;
}

.anim-cell {
    aspect-ratio: 1;
    transition: background-color 0.45s ease, border-color 0.45s ease, opacity 0.45s ease;
}

/* pixels — small squares, like a build coming to life */
.anim-pixels .anim-cell {
    background: var(--field-dot);
    border-radius: 2px;
}

.anim-pixels .anim-cell.lit { background: var(--accent); opacity: 0.85; }

/* dots — round, soft pulse */
.anim-dots .anim-cell {
    background: var(--field-dot);
    border-radius: 50%;
}

.anim-dots .anim-cell.lit { background: var(--accent); }

/* rings — hollow circles that fill */
.anim-rings .anim-cell {
    border: 1.5px solid var(--field-dot);
    border-radius: 50%;
    background: transparent;
}

.anim-rings .anim-cell.lit { border-color: var(--accent); background: var(--accent-dim); }

