
/* ---------- Fonts ----------
   Font files live in the fonts/ folder. Register each one with @font-face,
   then use its name in the variables below. */

@font-face {
    font-family: "Pirata One";
    src: url("fonts/PirataOne-Regular.ttf") format("truetype");
    /* The file only has one weight. Declaring it for the whole weight range makes the
       browser use it as-is for normal and bold text, instead of faking a bolder version. */
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

/* Metamorphous: used for "Game Designer" under your name.
   Expects fonts/Metamorphous-Regular.ttf; until that file is there, "Game Designer"
   falls back to the display font. */
@font-face {
    font-family: "Metamorphous";
    src: url("fonts/Metamorphous-Regular.ttf") format("truetype");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

/* Previous display font, no longer used (kept so it's easy to switch back:
   set --heading-font below to "Ostrich Sans") */
@font-face {
    font-family: "Ostrich Sans";
    src: url("fonts/OstrichSans-Heavy.otf") format("opentype");
    font-weight: 900;
    font-style: normal;
    font-display: swap;
}

/* Comfortaa: three weights from the same family */
@font-face {
    font-family: "Comfortaa";
    src: url("fonts/Comfortaa-Light.ttf") format("truetype");
    font-weight: 300;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Comfortaa";
    src: url("fonts/Comfortaa-Regular.ttf") format("truetype");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Comfortaa";
    src: url("fonts/Comfortaa-Bold.ttf") format("truetype");
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

:root {
    /* Display font: name, subtitle, navbar, titles and headings */
    --heading-font: "Pirata One", Georgia, serif;
    /* Reading font: summaries, body text, email, footer */
    --body-font: "Comfortaa", Arial, Helvetica, sans-serif;
    /* Subtitle font: section headings, the small line above a game name, "GAME DESIGNER".
       Metamorphous once fonts/Metamorphous-Regular.ttf is added; a classic serif until then. */
    --subtitle-font: "Metamorphous", Georgia, "Times New Roman", serif;

    /* ---------- Colors ---------- */
    --color-bg: #FAF3E5;     /* cream: page background */
    --color-text: #050517;   /* near-black navy: text, lines and borders */
    --color-nav: #A53824;    /* rust: the navbar pill fill (same in dark mode) */
    --color-nav-text: #FAF3E5; /* cream: navbar text and stars on the rust pill */
    --color-highlight: #A53824; /* rust: highlighted keywords in text */
    /* The star used in the navbar, the Games menu and the section dividers.
       A white shape on transparent; CSS fills it with each place's colour. */
    --star-icon: url("media/icons/NewStar.png");
}

/* Dark mode: the two colors swap places */
:root[data-theme="dark"] {
    --color-bg: #050517;
    --color-text: #D2CCB7;   /* stone (halfway between cream and khaki) in dark mode */
    --color-highlight: #E0583E; /* a brighter rust, readable on the dark background */
}

* {
    box-sizing: border-box;
}

/* Base text size: 21px (the browser default is 16px). Most sizes on the site are
   in rem/em, so they all scale from this. */
html {
    font-size: 131.25%;
}

body {
    margin: 0;
    font-family: var(--body-font);
    background: var(--color-bg);
    color: var(--color-text);
}

h1, h2, h3,
.subtitle,
nav a,
nav .dropdown-toggle {
    font-family: var(--heading-font);
}

/* Reading text is a bit smaller than the base size (~17px): Comfortaa is a wide font */
p {
    font-size: 0.8rem;
    line-height: 1.6;
}

/* ---------- Page spacing ----------
   --page-gutter: the space between the screen edge and the content.
   16px on phones up to 48px on large screens, plus 50px extra on tablets and desktops.
   The navbar, the reel and the content column all use it, so they line up. */
:root {
    /* the width of text and pictures on the game pages, centred in the 960px content column */
    --reading-width: 860px;
    --page-gutter: clamp(16px, 3vw, 48px);
    --nav-height: 52px; /* updated by script.js to the navbar's real height */
}

@media (min-width: 701px) {
    :root {
        --page-gutter: calc(clamp(16px, 3vw, 48px) + 50px);
    }
}

/* The page's content column. max-width caps how wide it gets on big screens. */
.box {
    max-width: 1440px;
    margin: 32px auto 50px;
    padding: 0 var(--page-gutter);
    display: grid;
    grid-template-columns: minmax(0, 1fr); /* never let wide content push the page wider than the screen */
    gap: 16px;
    position: relative;
}

/* ---------- Header: your name and title ---------- */

/* On most pages it sits at the top of the content; on the start page it's on the reel.
   Your name and title are centred. */
header {
    position: relative;
    text-align: center;
}

/* Logo slot on the right side of the header, outside the text's layout */
.logo {
    position: absolute;
    top: 50%;
    right: 0;
    transform: translateY(-50%);
    width: clamp(56px, 12vw, 96px);
    height: clamp(56px, 12vw, 96px);
}

.logo img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}

/* clamp(smallest, scales with page width, largest) */
/* Your name, a sword-shaped line under it, and "GAME DESIGNER" centred below.
   The block is exactly as wide as your name, so the line and title follow its width. */
header .title {
    display: inline-block;
    text-align: center;
}

header h1 {
    margin: 20px 0 0;
    font-size: clamp(2.3rem, 13.2vw, 7.75rem); /* up to about 163px */
    line-height: 1.1;
}

.subtitle {
    position: relative;
    --sword-height: max(16px, 0.75em); /* how tall the sword is */
    margin: 0.3em 0 24px;
    padding-top: calc(var(--sword-height) + 0.3em); /* the sword, then a little space before the text */
    font-family: var(--subtitle-font);
    /* about 0.27 x your name's size at every screen width (the name is clamp(2.3rem, 13.2vw, 7.75rem)),
       so the title always spans roughly three quarters of the name, like the design */
    font-size: clamp(0.63rem, 3.62vw, 2.125rem); /* up to about 45px (sized for Metamorphous) */
    line-height: 1.1;
    letter-spacing: 0.22em;
    text-indent: 0.22em; /* balances the letter spacing so the text stays centred */
    text-transform: uppercase;
    color: var(--color-text);
    opacity: 0.55; /* muted, like the grey in the design */
}

/* The sword between your name and title: a hilt (pommel, wrapped grip, curved crossguard)
   that keeps its shape, and a blade with a fuller and a pointed tip that stretches to
   fill the rest of your name's width. Drawn in the title's colour (currentColor). */
.subtitle::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: var(--sword-height);
    background: currentColor;
    --sword-hilt: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 24'%3E%3Ccircle cx='4.5' cy='12' r='4'/%3E%3Crect x='7.8' y='10.6' width='2' height='2.8' rx='0.5'/%3E%3Crect x='9.6' y='9.5' width='3.4' height='5' rx='1.2'/%3E%3Crect x='13.5' y='9.5' width='3.4' height='5' rx='1.2'/%3E%3Crect x='17.4' y='9.5' width='3.4' height='5' rx='1.2'/%3E%3Crect x='21.3' y='9.5' width='3.4' height='5' rx='1.2'/%3E%3Crect x='25.2' y='8.6' width='6' height='6.8' rx='1.2'/%3E%3Cpath d='M30 12C30 6.5 31.8 3.2 34 1.2L31.6 0.8C28.6 3.2 27 7 26.6 10.2V13.8C27 17 28.6 20.8 31.6 23.2L34 22.8C31.8 20.8 30 17.5 30 12Z'/%3E%3Crect x='30.5' y='8.6' width='9.5' height='6.8'/%3E%3C/svg%3E");
    --sword-blade: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 24' preserveAspectRatio='none'%3E%3Cpath fill-rule='evenodd' d='M0 8.6H366L400 12L366 15.4H0Z M4 11.25H318V12.75H4Z'/%3E%3C/svg%3E");
    -webkit-mask:
        var(--sword-hilt) left center / auto 100% no-repeat,
        var(--sword-blade) right center / calc(100% - var(--sword-height) * 40 / 24 + 1px) 100% no-repeat;
    mask:
        var(--sword-hilt) left center / auto 100% no-repeat,
        var(--sword-blade) right center / calc(100% - var(--sword-height) * 40 / 24 + 1px) 100% no-repeat;
}

/* ---------- Start page: full-screen reel ----------
   The reel fills the screen below the navbar, with your name and title on top.
   The video file is media/reel.mp4 (see index.html). Until it exists, the area
   shows the dark background with your name on it. */
.hero {
    position: relative;
    display: flex;
    align-items: center;
    height: calc(100svh - var(--nav-height));
    min-height: 360px;
    overflow: hidden;
    background: #050517; /* shown behind / instead of the video */
    color: #FAF3E5;      /* always cream on the reel, in light and dark mode */
}

.hero-video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover; /* fills the screen, cropping the edges if the shapes differ */
}

/* Even dark shading over the whole reel, a little stronger in the middle behind your
   centred name and title, so they're readable whatever the footage looks like */
.hero::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    background:
        radial-gradient(ellipse 60% 45% at 50% 50%, rgba(5, 5, 23, 0.35), rgba(5, 5, 23, 0) 100%),
        rgba(5, 5, 23, 0.4);
    pointer-events: none;
}

.hero header {
    position: relative;
    z-index: 2;
    width: 100%;
    padding: 0 var(--page-gutter);
}

/* On the reel: cream name; line and title in a softer cream */
.hero .subtitle {
    margin-bottom: 0;
    color: #FAF3E5;
    opacity: 0.75;
}

/* ---------- Navigation: full-width bar at the top of every page ---------- */

nav {
    position: sticky; /* stays at the top while scrolling */
    top: 0;
    z-index: 100;
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 0 var(--page-gutter);
    background: var(--color-nav);
    color: var(--color-nav-text);
}

/* Options from the left: HOME ✦ GAMES ✦ ABOUT ME */
nav ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    align-items: center;
    gap: 10px;
}

nav li {
    flex: none;
}

nav > ul > li {
    position: relative;
    display: flex;
    align-items: center;
}

/* Navbar links and dropdown game names, as written ("Home", "Games", "About Me") */
nav a,
.dropdown-toggle {
    letter-spacing: 0.04em;
}

nav a {
    display: block;
    color: var(--color-nav-text);
    text-decoration: none;
}

nav > ul > li > a,
nav .dropdown-toggle {
    font-size: clamp(0.85rem, 1.6vw, 1.05rem);
    padding: 14px 6px;
    white-space: nowrap;
}

/* Small star between the options */
nav > ul > li.nav-star {
    width: 42px;
    aspect-ratio: 702 / 364;
    background: currentColor;
    -webkit-mask: var(--star-icon) center / contain no-repeat;
    mask: var(--star-icon) center / contain no-repeat;
    user-select: none;
}

/* Hover: the text grows a little (from its left edge, so it doesn't nudge its neighbours) */
nav a,
.dropdown-toggle {
    transition: transform 0.15s ease, letter-spacing 0.2s ease;
    transform-origin: left center;
}

nav > ul > li > a:hover,
nav .dropdown-toggle:hover,
nav .dropdown.open .dropdown-toggle {
    transform: scale(1.1);
}

/* Current page: underlined (Pirata One has no bold, so bold wouldn't show) */
nav > ul > li > a.active,
nav .dropdown-toggle.active .dropdown-label {
    text-decoration: underline;
    text-decoration-thickness: 2px;
    text-underline-offset: 5px;
}

/* ---------- Games dropdown ---------- */

.dropdown {
    position: relative;
}

.dropdown-toggle {
    border: 0;
    background: none;
    font: inherit;
    color: var(--color-nav-text);
    cursor: pointer;
}

/* "GAMES ▾": the arrow sits just to the right of the word */
.dropdown-label {
    position: relative;
    padding-right: 0.9em; /* room for the arrow */
}

.dropdown-arrow {
    position: absolute;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    font-size: 0.8em;
    letter-spacing: 0;
    line-height: 1;
}

/* The menu drops straight down from the bar, in the same rust */
.dropdown-menu {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    min-width: 260px;
    z-index: 10;
    list-style: none;
    margin: 0;
    padding: 6px 0 10px;
    background: var(--color-nav);
}

.dropdown-menu a {
    padding: 10px 16px;
    color: var(--color-nav-text);
    transform-origin: left center;
}

/* Game names spread their letters out a little on hover */
.dropdown-menu a:hover {
    letter-spacing: 0.14em;
}

/* A small star between the games, like the stars in the navbar */
.dropdown-menu li + li::before {
    content: "";
    display: block;
    margin-left: 16px;
    width: 28px;
    aspect-ratio: 702 / 364;
    background: var(--color-nav-text);
    -webkit-mask: var(--star-icon) center / contain no-repeat;
    mask: var(--star-icon) center / contain no-repeat;
}

.dropdown-menu a.active {
    text-decoration: underline;
    text-decoration-thickness: 2px;
    text-underline-offset: 4px;
}

.dropdown.open .dropdown-menu {
    display: block;
}

/* Open on hover too, but only on devices with a real mouse */
@media (hover: hover) {
    .dropdown:hover .dropdown-menu {
        display: block;
    }

    .dropdown:hover .dropdown-toggle {
        transform: scale(1.1);
    }
}

/* Dark mode button: at the right end of the navbar */
.theme-toggle {
    flex: none;
    margin-left: auto;
    width: 32px;
    height: 32px;
    padding: 0;
    border: var(--color-nav-text) 2px solid;
    border-radius: 50%;
    background: none;
    color: var(--color-nav-text);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    transition: transform 0.15s ease;
}

.theme-toggle:hover {
    transform: scale(1.15);
}

/* The sun / moon icon (drawn by script.js), centred in the circle */
.theme-toggle {
    display: grid;
    place-items: center;
}

.theme-toggle svg {
    width: 18px;
    height: 18px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* the sun a little bigger than the moon */
.theme-toggle svg.sun-icon {
    width: 21px;
    height: 21px;
}

/* the sun's middle is a solid disc */
.theme-toggle .sun-disc {
    fill: currentColor;
}

/* Phones: slightly tighter so everything fits on one row */
@media (max-width: 600px) {
    nav {
        gap: 8px;
    }

    nav ul {
        gap: 6px;
    }

    nav > ul > li > a,
    nav .dropdown-toggle {
        padding: 14px 3px;
        letter-spacing: 0.05em;
    }

    .dropdown-menu {
        min-width: 230px;
    }
}

/* ---------- Games ---------- */

/* Shared spacing on every page */
main {
    display: grid;
    gap: 32px; /* between blocks of content, same as trailer ↔ text on the start page */
    /* 16px page gap + 42.5px = 58.5px below the navbar,
       the same as the space between a game and the divider below it */
    margin-top: 42.5px;
}

/* Space between the game rows on the start page */
#games {
    gap: 120px;
}

/* ---------- Dividers ----------
   Two rust line halves with a four-pointed star between them. Each half is its
   own bar, so both of its ends are rounded. Used between the rows on the start
   page, and at the top of the footer on every page. */
:root {
    --star-width: 120px; /* the divider star, including its long side points */
    /* distance from the center to the inner end of each half: half the star,
       plus a small gap so the star stands free of the lines */
    --divider-gap: calc(var(--star-width) / 2 + 10px);
}

/* Between rows on the start page: above every game except a first one
   (so also between the intro and the first game), centered in the 120px gap
   (58.5px above, 3px line, 58.5px below) */
#games > * + .game,
footer {
    position: relative;
}

/* Line halves: ::before = left half, ::after = right half */
#games > * + .game::before,
#games > * + .game::after,
footer::before,
footer::after {
    content: "";
    position: absolute;
    height: 3px;
    border-radius: 3px;
    background: var(--color-nav);
}

#games > * + .game::before,
footer::before {
    left: 0;
    right: calc(50% + var(--divider-gap));
}

#games > * + .game::after,
footer::after {
    left: calc(50% + var(--divider-gap));
    right: 0;
}

#games > * + .game::before,
#games > * + .game::after {
    top: -61.5px;
}

/* Footer: the divider sits along its top edge */
footer::before,
footer::after {
    top: 0;
}

/* The star. Between games it hangs off the trailer box but is positioned against
   the game row; in the footer it hangs off the first line of text. */
#games > * + .game > .trailer::after,
footer > :first-child::before,
.game-updates > h3::before,
.page-section > h3::before {
    content: "";
    position: absolute;
    left: 50%;
    transform: translate(-50%, -50%);
    /* the star picture (media/icons/NewStar.png), coloured rust, in the gap
       between the two line halves */
    width: var(--star-width);
    aspect-ratio: 702 / 364;
    background: var(--color-nav);
    -webkit-mask: var(--star-icon) center / contain no-repeat;
    mask: var(--star-icon) center / contain no-repeat;
}

#games > * + .game > .trailer::after {
    top: -60px; /* center of the line (-61.5px + half of 3px) */
}

footer > :first-child::before,
.game-updates > h3::before,
.page-section > h3::before {
    top: 1.5px; /* center of the line along the top edge */
}

/* Who made the game and when, in small italics under the title */
.game-credit {
    font-size: 0.65rem;
    font-style: italic;
    margin: 4px 0 0;
}

/* On the start page: sit close under the title, with space before the summary */
.summary h2:has(+ .game-credit) {
    margin-bottom: 0;
}

.summary .game-credit {
    margin-bottom: 1em;
}

/* Small print at the end of a game's text: platforms, legal notices */
.game-notes {
    margin-top: 1.5em;
}

.game-notes p {
    margin: 0 0 4px;
    font-size: 0.65rem;
    font-style: italic;
    line-height: 1.5;
}

/* Store links in the small print: text colored, underlined, rust on hover */
.game-notes a {
    color: var(--color-text);
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
}

.game-notes a:hover {
    color: var(--color-nav);
}

/* On a game page this sits in the page grid, which already adds space above */
main > .game-notes {
    margin-top: 0;
}

/* Small print right under a trailer (e.g. a copyright notice) */
.trailer-note {
    margin: 0;
    font-size: 0.65rem;
    font-style: italic;
    line-height: 1.5;
}

/* Game page: pull it up close to the trailer (the page grid adds 32px) */
main > .trailer + .trailer-note {
    margin-top: -24px;
}

/* Start page, side by side: the note goes under the trailer in the left column,
   while the text column spans both rows */
@media (min-width: 1001px) {
    .game:has(> .trailer-note) {
        row-gap: 8px;
        /* keep the trailer row from stretching when the text column is tall */
        grid-template-rows: auto 1fr;
    }

    .game:has(> .trailer-note) > .trailer {
        grid-column: 1;
        grid-row: 1;
    }

    .game:has(> .trailer-note) > .trailer-note {
        grid-column: 1;
        grid-row: 2;
    }

    .game:has(> .trailer-note) > .summary {
        grid-column: 2;
        grid-row: 1 / span 2;
    }
}

/* Extra videos under a game (e.g. "Updates for Battlemarked"): full width,
   below the trailer and text, three videos side by side */
.game > .game-updates {
    grid-column: 1 / -1;
    margin-top: 24px; /* plus the row gap above it */
}

/* The same star divider as between games, across the top of the section.
   .page-section is for any titled section on a page (e.g. My contributions). */
.game-updates,
.page-section {
    position: relative;
    padding-top: 27px; /* 3px line + 24px space before the heading */
}

.game-updates::before,
.game-updates::after,
.page-section::before,
.page-section::after {
    content: "";
    position: absolute;
    top: 0;
    height: 3px;
    border-radius: 3px;
    background: var(--color-nav);
}

.game-updates::before,
.page-section::before {
    left: 0;
    right: calc(50% + var(--divider-gap));
}

.game-updates::after,
.page-section::after {
    left: calc(50% + var(--divider-gap));
    right: 0;
}

.game-updates h3,
.page-section > h3 {
    margin: 0 0 16px;
}

/* Section text: comfortable reading width; the first paragraph sits right under the heading */
.page-section > p {
    max-width: 44em;
}

.page-section > h3 + p {
    margin-top: 0;
}

/* Carousel: arrow, scrolling row of videos, arrow */
.carousel {
    display: flex;
    align-items: center;
    gap: 12px;
}

/* The row of videos: shows 3 at a time and scrolls sideways, snapping to whole videos */
.update-videos {
    --visible: 3;
    flex: 1;
    min-width: 0;
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: calc((100% - (var(--visible) - 1) * 16px) / var(--visible));
    gap: 16px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    scrollbar-width: none; /* hide the scrollbar: the arrows do the job */
}

.update-videos::-webkit-scrollbar {
    display: none;
}

.update-videos > * {
    scroll-snap-align: start;
}

/* Arrow buttons: rust circles with cream chevrons, like the play buttons */
.carousel-arrow {
    flex: none;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--color-nav);
    cursor: pointer;
    position: relative;
    transition: transform 0.15s ease;
}

/* The chevron: two sides of a rotated square */
.carousel-arrow::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 10px;
    height: 10px;
    border-top: 3px solid var(--color-nav-text);
    border-right: 3px solid var(--color-nav-text);
    border-radius: 1px;
}

.carousel-prev::before {
    transform: translate(-30%, -50%) rotate(-135deg);
}

.carousel-next::before {
    transform: translate(-70%, -50%) rotate(45deg);
}

.carousel-arrow:hover,
.carousel-arrow:focus-visible {
    transform: scale(1.15);
}

.carousel-arrow:focus-visible {
    outline: 3px solid var(--color-nav);
    outline-offset: 3px;
}

/* When all videos already fit (too few to scroll), the arrows are hidden
   but keep their space, so the videos stay in the same place */
.carousel.all-visible .carousel-arrow {
    visibility: hidden;
}

/* Video thumbnail link: just the sharp full-size (1280x720) thumbnail,
   linking to the video on YouTube (built by script.js from SITE_VIDEO_LISTS). */
.yt-thumb {
    position: relative;
    display: block;
    width: 100%;
    padding: 0;
    border: 0;
    background: #000;
    cursor: pointer;
    overflow: hidden;
}

.yt-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.25s ease;
}

/* Hover: the image zooms in slightly inside its frame, so it feels clickable */
.yt-thumb:hover img,
.yt-thumb:focus-visible img {
    transform: scale(1.06);
}

.yt-thumb:focus-visible {
    outline: 3px solid var(--color-nav);
    outline-offset: 3px;
}

/* Phones: one video at a time, smaller arrows */
@media (max-width: 1000px) {
    .game > .game-updates {
        margin-top: 0;
    }
}

/* Smaller screens: tighter gaps and smaller arrows, so three videos still fit */
@media (max-width: 700px) {
    .update-videos {
        gap: 10px;
        grid-auto-columns: calc((100% - (var(--visible) - 1) * 10px) / var(--visible));
    }

    .carousel {
        gap: 8px;
    }

    .carousel-arrow {
        width: 34px;
        height: 34px;
    }
}

/* Narrow phones: three would be too small to make out, so one at a time */
@media (max-width: 600px) {
    .update-videos {
        --visible: 1;
    }
}

/* Start page, stacked: trailer, note, then the text */
@media (max-width: 1000px) {
    .game > .trailer + .trailer-note {
        margin-top: -24px;
    }
}

/* Intro message at the top of the start page */
.intro p {
    margin: 0 auto; /* centers the text block */
    max-width: 36em;
    text-align: center;
    font-size: 0.9rem;
    line-height: 1.6;
}

.game,
.about {
    display: grid;
    /* minmax(0, ...) lets the columns shrink below the trailer's built-in minimum width */
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    gap: 32px;
}

.trailer {
    aspect-ratio: 16 / 9;
}

.trailer iframe,
.trailer video {
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
}

.summary h2,
.about-text h2 {
    margin-top: 0;
}

.summary h2 a {
    color: var(--color-text);
    text-decoration-thickness: 3px;
    text-underline-offset: 4px;
}

.summary h2 a:hover {
    text-decoration: none;
}

/* Small line above a game's name, e.g. "Demeo x Dungeons & Dragons" */
.title-prefix {
    display: block;
    font-size: 0.55em;
    font-weight: normal;
    letter-spacing: 0.05em;
    margin-bottom: 2px;
}

/* Menu text is already small, so the prefix shrinks less there */
.dropdown-menu .title-prefix {
    font-size: 0.75em;
}

/* ---------- Game pages ---------- */

/* The big trailer on a game page: full width on smaller screens, capped on large ones
   so it doesn't fill the whole screen. Left-aligned under the title. */
.game-page > .trailer {
    max-width: 960px;
    width: 100%;
}

/* Big page titles at the top left: game names and "About Me" */
.game-title,
.page-title {
    margin: 0;
    font-size: 2rem;
}

/* On a game page (and About Me / TTRPG) the page's own title is the header, so it's bigger */
.game-page .game-title,
.about-page .page-title,
.page .page-title {
    font-size: clamp(2.4rem, 7vw, 4.5rem); /* up to about 95px */
    line-height: 1.05;
}

.game-details {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 32px;
}

.game-details h3 {
    margin-top: 0;
}

/* ---------- About ---------- */

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

.portrait {
    aspect-ratio: 1 / 1;
}

/* General text pages (e.g. TTRPG): comfortable reading width */
.page-text {
    max-width: 40em;
}

.page-text > :first-child {
    margin-top: 0;
}

/* Placeholder notice on unfinished pages, in the display font like the navbar */
.under-construction {
    font-family: var(--heading-font);
    font-size: 1.25rem;
    letter-spacing: 0.15em;
    text-transform: uppercase;
}

/* Text starts level with the top of the photo */
.about-text > :first-child {
    margin-top: 0;
}

.portrait img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Footer: email on the left, copyright on the right */
footer {
    display: flex;
    flex-wrap: wrap; /* on very narrow screens the copyright drops below the email */
    justify-content: space-between;
    align-items: baseline;
    gap: 6px 24px;
    /* 16px page gap + 42.5px = 58.5px above the divider line, like every divider */
    margin-top: 42.5px;
    /* 3px line + 28px space before the email and copyright */
    padding: 31px 0 16px;
}

footer p {
    margin: 0;
    font-size: 0.65rem; /* about 14px, the same as the small print under the games */
}

.copyright {
    margin-left: auto; /* stays on the right even when it wraps to its own line */
}

/* Stack things on narrow screens */
/* Start-page rows (trailer + text) stack below 1000px, so the trailer never gets
   narrower than about 480px beside the text */
@media (max-width: 1000px) {
    .game {
        grid-template-columns: minmax(0, 1fr);
    }
}

@media (max-width: 700px) {
    .about,
    .game-details {
        grid-template-columns: minmax(0, 1fr);
    }

}


/* ---------- Start page: two games side by side ----------
   Games marked "game-half" (Spatial Ops and Home Sports) sit next to each other in
   two columns, each with its trailer on top and its text below. One star divider
   spans both columns above them. Below 1000px wide they stack like the other games. */
@media (min-width: 1001px) {
    #games {
        --half-gap: 48px; /* space between the two columns */
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        column-gap: var(--half-gap);
    }

    /* everything else on the start page still spans the full width */
    #games > :not(.game-half) {
        grid-column: 1 / -1;
    }

    /* inside each half: trailer on top, text below */
    #games > .game-half {
        grid-template-columns: minmax(0, 1fr);
        gap: 32px;
        align-content: start;
    }

    /* The divider above the pair: drawn once, by the left game, across both columns */
    #games > .game-half:has(+ .game-half)::before {
        right: calc(var(--divider-gap) - var(--half-gap) / 2);
    }

    #games > .game-half:has(+ .game-half)::after {
        left: calc(100% + var(--half-gap) / 2 + var(--divider-gap));
        right: calc(-100% - var(--half-gap));
    }

    #games > .game-half:has(+ .game-half) > .trailer::after {
        left: calc(100% + var(--half-gap) / 2);
    }

    /* ...so the right game doesn't draw a second one */
    #games > .game-half + .game-half::before,
    #games > .game-half + .game-half::after,
    #games > .game-half + .game-half > .trailer::after {
        display: none;
    }
}
/* ---------- Start page: Battlemarked as a centred feature ----------
   The game marked "game-feature" shows its trailer centred, with the copyright note
   and the text block underneath, in one centred column (capped at 960px like the
   game pages). Its "Updates for ..." carousel stays full width below. */
#games > .game-feature {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: none;
    row-gap: 32px;
}

#games > .game-feature > .trailer,
#games > .game-feature > .trailer-note,
#games > .game-feature > .summary {
    grid-column: 1;
    grid-row: auto;
    justify-self: center;
    width: 100%;
    max-width: 960px;
}

/* the copyright note sits just under the trailer */
#games > .game-feature > .trailer + .trailer-note {
    margin-top: -24px;
}
/* ---------- Store logos ("Available on ...") ----------
   Each store is its logo, linking to the store page. The logos are single-colour
   files in media/icons/ (from Simple Icons) drawn in the text colour, so they work
   in light and dark mode. The store name shows as a tooltip and is read by screen readers. */
.store-links {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 14px;
}

.store-link {
    display: inline-flex;
    align-items: center;
    color: var(--color-text);
    text-decoration: none;
    transition: color 0.15s ease, transform 0.15s ease;
}

.store-link:hover,
.store-link:focus-visible {
    color: var(--color-nav);
    transform: scale(1.15);
}

.store-icon {
    display: block;
    width: 1.6em;
    height: 1.6em;
    background: currentColor;
    -webkit-mask: var(--icon) center / contain no-repeat;
    mask: var(--icon) center / contain no-repeat;
}

/* A store without a logo file yet (Pico): its name as a small badge instead */
.store-badge {
    height: 1.6em;
    padding: 0 0.45em;
    border: 2px solid currentColor;
    font-style: normal;
    font-weight: 700;
    font-size: 0.85em;
    letter-spacing: 0.08em;
}
/* Start page, every game: "Summary of the game" on the left and "My responsibilities"
   on the right, side by side under the title. The title, credit and store logos stay
   full width. Stacks on phones, and in the two half-width games when they're too narrow. */
#games > .game > .summary {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: 40px;
    align-items: start;
}

#games > .game > .summary > * {
    grid-column: 1 / -1;
}

#games > .game > .summary > .summary-text {
    grid-column: 1;
    grid-row: 3;
    margin-top: 0;
}

#games > .game > .summary > .summary-responsibilities {
    grid-column: 2;
    grid-row: 3;
}

.summary-text > h3,
.summary-responsibilities > h3 {
    margin-top: 0;
}

/* Responsibilities on the start page: a short list with rust bullets */
.responsibility-list {
    margin: 0;
    padding-left: 1.2em;
    font-size: 0.9rem;
    line-height: 1.6;
}

/* The game summary on the start page: the same size as the responsibilities beside it */
.summary-text p {
    font-size: 0.9rem;
    line-height: 1.6;
}

.responsibility-list li + li {
    margin-top: 0.2em;
}

.responsibility-list li::marker {
    color: var(--color-highlight);
}

/* Stacked: one column, summary first, responsibilities under it */
@media (max-width: 600px) {
    #games > .game > .summary > .summary-text,
    #games > .game > .summary > .summary-responsibilities {
        grid-column: 1 / -1;
        grid-row: auto;
    }
}

/* Spatial Ops and Home Sports side by side leave each text block only half the
   width; between 1001px and 1279px that's too narrow for two text columns */
@media (min-width: 1001px) and (max-width: 1279px) {
    #games > .game-half > .summary > .summary-text,
    #games > .game-half > .summary > .summary-responsibilities {
        grid-column: 1 / -1;
        grid-row: auto;
    }
}
/* Text only for screen readers: hidden on the page, but read out loud */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}
/* Start page: each game's title with its store logos on the same row, the logos pushed
   to the right edge (under the right side of the trailer). If they don't fit next to
   each other, the logos wrap onto their own line under the title. */
.game-title-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px 24px;
}

#games .game-title-row h2 {
    margin: 0;
    font-size: clamp(2rem, 4.2vw, 3rem); /* up to about 63px */
    line-height: 1.05;
}

.game-title-row .game-notes,
.game-title-row .store-links {
    margin: 0;
}

/* slightly bigger logos next to the bigger titles */
.game-title-row .store-icon {
    width: 1.9em;
    height: 1.9em;
}

.game-title-row + .game-credit {
    margin-top: 6px;
}
/* when the logos wrap under the title, keep them on the right */
.game-title-row .game-notes {
    margin-left: auto;
}
/* Logos sized to the game titles on the start page: about 0.6 x the title's size
   (the title is clamp(2rem, 4.2vw, 3rem)), so they match its capital letters */
.game-title-row .store-links {
    gap: 8px clamp(10px, 1.1vw, 18px);
}

.game-title-row .store-icon {
    width: clamp(1.25rem, 2.5vw, 1.8rem);   /* up to about 38px */
    height: clamp(1.25rem, 2.5vw, 1.8rem);
}

.game-title-row .store-badge {
    height: clamp(1.25rem, 2.5vw, 1.8rem);
    font-size: clamp(0.55rem, 1.05vw, 0.8rem);
}

/* Line the logos' bottoms up with the baseline of the game's name
   (the last line of the title, under any small prefix line) */
.game-title-row {
    align-items: flex-end;
    align-items: last baseline;
}

/* Game pages: bigger logos too (about 30px) */
.game-page .store-icon {
    width: 2.1em;
    height: 2.1em;
}

.game-page .store-badge {
    height: 2.1em;
}

.game-page .store-links {
    gap: 6px 16px;
}
/* Games with a small line above the name (Battlemarked's "Demeo x Dungeons & Dragons"):
   the logos line up with that small line, centred on it, instead of the name below */
.game-title-row {
    --title-size: clamp(2rem, 4.2vw, 3rem);    /* same as the title */
    --icon-size: clamp(1.25rem, 2.5vw, 1.8rem); /* same as the logos */
}

.game-title-row:has(.title-prefix) {
    align-items: flex-start;
}

.game-title-row:has(.title-prefix) .game-notes {
    /* centre of the small line (0.55 x title size, line height 1.05) minus half a logo */
    margin-top: calc(var(--title-size) * 0.55 * 1.05 / 2 - var(--icon-size) / 2);
}
/* Subtitles in the subtitle font (Metamorphous): section headings like
   "Summary of the game" and "My responsibilities". Main titles, and the small line above
   a game's name ("Demeo x Dungeons & Dragons"), stay in the display font. */
h3 {
    font-family: var(--subtitle-font);
}

.title-prefix {
    font-family: var(--heading-font);
}
/* Start page: the two column headings ("Summary of the game", "My responsibilities")
   are a bit smaller than elsewhere, so they stay on one line in the narrower columns */
#games .summary h3 {
    font-size: 0.88rem; /* about 18px */
}
/* ---------- Navbar: contact icons on the right (email, LinkedIn), then dark mode ---------- */
.nav-right {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 14px;
}

.nav-icon {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 0;
    background: none;
    color: var(--color-nav-text);
    cursor: pointer;
    transition: transform 0.15s ease;
}

.nav-icon svg {
    width: 24px;
    height: 24px;
    display: block;
}

.nav-icon:hover,
.nav-icon:focus-visible {
    transform: scale(1.15);
}

/* "Email copied!": a small note that pops up under the envelope */
.copy-note {
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    padding: 6px 10px;
    background: var(--color-text);
    color: var(--color-bg);
    font-family: var(--subtitle-font); /* Metamorphous */
    font-size: 0.65rem;
    white-space: nowrap;
    opacity: 0;
    transform: translateY(-4px);
    pointer-events: none;
    transition: opacity 0.15s ease, transform 0.15s ease;
}

.nav-icon.show-note .copy-note {
    opacity: 1;
    transform: translateY(0);
}

/* Phones: a little tighter so everything still fits on one row */
@media (max-width: 600px) {
    .nav-right {
        gap: 6px;
    }

    .nav-icon {
        width: 28px;
        height: 28px;
    }

    .nav-icon svg {
        width: 21px;
        height: 21px;
    }
}
/* Narrow phones: drop the decorative stars between the links and tighten a little,
   so the links, contact icons and dark mode button all fit on one row
   (680px: with five options, the stars need this much room) */
@media (max-width: 680px) {
    nav > ul > li.nav-star {
        display: none;
    }

    nav ul {
        gap: 8px;
    }

    .nav-right {
        gap: 2px;
    }

    .nav-icon {
        width: 26px;
    }

    nav > ul > li > a,
    nav .dropdown-toggle {
        padding-left: 2px;
        padding-right: 2px;
        letter-spacing: 0.02em;
    }
}
/* Very narrow phones (under 340px): slightly smaller link text so the row keeps its edge spacing */
@media (max-width: 340px) {
    nav > ul > li > a,
    nav .dropdown-toggle {
        font-size: 0.8rem;
    }
}
/* Bigger navbar icons (email, LinkedIn, dark mode) */
.nav-icon {
    width: 40px;
    height: 40px;
}

.nav-icon svg {
    width: 30px;
    height: 30px;
}

.theme-toggle {
    width: 36px;
    height: 36px;
    font-size: 1.15rem;
}

@media (max-width: 600px) {
    .nav-icon {
        width: 32px;
        height: 32px;
    }

    .nav-icon svg {
        width: 25px;
        height: 25px;
    }

    .theme-toggle {
        width: 30px;
        height: 30px;
        font-size: 1rem;
    }
}

@media (max-width: 400px) {
    .nav-icon {
        width: 29px;
    }
}
/* ---------- Other pages: centred like the start page ----------
   The page title (and a game's credit line) is centred at the top, and everything
   below sits in one centred column, up to 960px wide, the same as Battlemarked's
   column on the start page. Text inside the column stays left-aligned for reading. */
main.game-page,
main.about-page,
main.page {
    justify-items: center;
}

main.game-page > *,
main.about-page > *,
main.page > * {
    width: 100%;
    max-width: 960px;
}

.game-page .game-heading,
.about-page .page-title,
.page .page-title {
    text-align: center;
}

/* Game pages: the store logos centred under the text boxes */
.game-page .store-links {
    justify-content: center;
}

/* TTRPG: the "under construction" notice centred too */
.page .page-text {
    max-width: 960px;
    text-align: center;
}
/* Game pages: sections with a divider line on top ("Updates for ...", "My contributions" ...)
   span the full width, so their dividers match the others, while their content stays in
   the centred 960px column (the side padding fills the space either side of it) */
main.game-page > .game-updates,
main.game-page > .page-section {
    max-width: none;
    padding-left: max(0px, calc((100% - 960px) / 2));
    padding-right: max(0px, calc((100% - 960px) / 2));
}
/* Start page: more room between a game's title block (title + credit) and the
   "Summary of the game" / "My responsibilities" columns below it */
#games .summary .game-credit {
    margin-bottom: 36px;
}
/* Game pages: the store logos sit centred just under the title, where the
   "Resolution Games" line used to be, at about the size of the start page's logos */
.game-heading .game-notes {
    margin-top: 26px;
}

.game-heading .store-links {
    gap: 8px clamp(12px, 1.3vw, 20px);
}

.game-heading .store-icon {
    width: clamp(1.5rem, 2.6vw, 1.8rem);   /* up to about 38px */
    height: clamp(1.5rem, 2.6vw, 1.8rem);
}

.game-heading .store-badge {
    height: clamp(1.5rem, 2.6vw, 1.8rem);
    font-size: clamp(0.6rem, 1.1vw, 0.8rem);
}
/* Subheadings inside a section (e.g. Narrative / Encounter / Combat under
   "My contributions"): the subtitle font, smaller than the section heading */
/* My contributions: Narrative, Encounter and Combat side by side.
   Stacks into one column on narrow screens. */
.contribution-columns {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 32px;
    margin-top: 1.6em;
}

@media (max-width: 800px) {
    .contribution-columns {
        grid-template-columns: 1fr;
        gap: 1.6em;
    }
}

.page-section > h4,
.contribution > h4 {
    margin: 1.6em 0 0.4em;
    font-family: var(--subtitle-font);
    font-size: 0.9rem; /* about 19px; section headings are about 25px */
    font-weight: normal;
    letter-spacing: 0.04em;
}

/* Each column is a framed card with square corners: a thin rust border, a faint fill, and its heading
   centred over a short rust rule */
.contribution {
    padding: 22px 22px 24px;
    border: 1px solid color-mix(in srgb, var(--color-nav) 55%, transparent);
    background: color-mix(in srgb, var(--color-text) 4%, transparent);
}

.contribution > h4 {
    margin-top: 0;
    margin-bottom: 16px;
    text-align: center;
}

.contribution > h4::after {
    content: "";
    display: block;
    width: 40px;
    height: 2px;
    margin: 8px auto 0;
    border-radius: 2px;
    background: var(--color-nav);
}

.page-section > h4 + p {
    margin-top: 0;
    max-width: 44em;
}
/* Bulleted points in a section (e.g. under Narrative) */
.section-points {
    margin: 0;
    padding-left: 1.2em;
    max-width: 44em;
    font-size: 0.8rem; /* same as paragraphs */
    line-height: 1.6;
}

.section-points li + li {
    margin-top: 0.6em;
}

.section-points li::marker {
    color: var(--color-highlight);
}

/* Highlighted keywords: bold and red */
.highlight {
    font-weight: 700;
    color: var(--color-highlight);
}
/* A box that links to another site, e.g. the official Spatial Ops page */
.link-box {
    display: block;
    width: fit-content;
    max-width: 100%;
    margin: 40px auto 0;
    padding: 18px 32px;
    border: 2px solid var(--color-highlight);
    color: var(--color-text);
    text-align: center;
    text-decoration: none;
    transition: transform 0.15s ease, background-color 0.15s ease;
}

.link-box:hover,
.link-box:focus-visible {
    transform: scale(1.03);
    background: color-mix(in srgb, var(--color-highlight) 12%, transparent);
}

.link-box-title {
    display: block;
    font-family: var(--subtitle-font);
    font-size: 1.1rem;
}

.link-box-url {
    display: block;
    margin-top: 4px;
    font-size: 0.75rem;
    color: var(--color-highlight);
}
/* Personal projects: a compact list, one row per project */
.project-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.project {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 16px 0;
    border-bottom: 1px solid color-mix(in srgb, var(--color-text) 20%, transparent);
}

.project:last-child {
    border-bottom: none;
}

/* Small picture at the start of each row */
.project-thumb {
    flex-shrink: 0;
    width: 144px;
    aspect-ratio: 16 / 10;
    object-fit: cover;
}

/* Name, length and roles each on their own line */
.project-info {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

/* Phones: a smaller picture so the text keeps room */
@media (max-width: 500px) {
    .project-thumb {
        width: 88px;
    }
}

.project-name {
    margin: 0;
    font-family: var(--subtitle-font);
    font-size: 1rem;
    font-weight: normal;
}

.project-length {
    margin: 0;
    font-size: 0.7rem;
    opacity: 0.7;
}

/* Roles as plain text on their own line under the name, separated by commas */
.project-roles {
    flex-basis: 100%;
    display: flex; /* flex drops the gaps between the <li>s, so no space before each comma */
    flex-wrap: wrap;
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: 0.75rem;
}

.project-roles li + li::before {
    content: ",\00a0";
}

/* The link at the end of each row: a store logo (Steam, itch.io) like on the game
   pages, or a small text badge (GDC). Hover turns it rust, like the store logos. */
.project-link {
    flex-shrink: 0;
}

.project .store-icon {
    width: 1.8rem;
    height: 1.8rem;
}

/* The GDC badge: a square the same size as the logos, so they all line up */
.project .store-badge {
    width: 1.8rem;
    height: 1.8rem;
    padding: 0;
    justify-content: center;
    font-size: 0.55rem;
    letter-spacing: 0.02em;
}
/* A short intro paragraph under a page title (e.g. Other Projects) */
.page-intro {
    max-width: 40em;
    margin: 0 auto 24px;
    font-size: 0.8rem;
    line-height: 1.6;
    text-align: center;
}
/* A picture shown whole instead of cropped (e.g. a wide logo), on black */
.project-thumb-fit {
    object-fit: contain;
    background: #000;
}
/* The thumbnails link to the same place as the logo at the end of the row */
.project-thumb-link {
    display: block;
    flex-shrink: 0;
    transition: transform 0.15s ease, filter 0.15s ease;
}

.project-thumb-link:hover {
    transform: scale(1.04);
    filter: brightness(1.1);
}

.project-thumb-link .project-thumb {
    display: block;
}
/* The divider line halves taper to a point at both ends, like the star's side points:
   full thickness in the middle of each half, narrowing to nothing at its ends. */
#games > * + .game::before,
#games > * + .game::after,
footer::before,
footer::after,
.game-updates::before,
.game-updates::after,
.page-section::before,
.page-section::after {
    border-radius: 0;
    /* full thickness along the middle, tapering over the last --line-taper at each end */
    --line-taper: 90px;
    clip-path: polygon(0 50%, var(--line-taper) 0, calc(100% - var(--line-taper)) 0, 100% 50%,
                       calc(100% - var(--line-taper)) 100%, var(--line-taper) 100%);
    /* 5px at the thickest; the -1px keeps its middle on the same line as the
       star (the positions above were set for a 3px line) */
    height: 5px;
    margin-top: -1px;
}
/* Game pages: section titles ("Updates for ...", "My contributions", "Additional work" ...)
   centred, under the divider star */
.game-page .page-section > h3,
.game-page .game-updates > h3 {
    text-align: center;
    padding-top: 14px; /* room for the star's bottom point, which now sits right above */
}
/* Sections a link jumps to (e.g. game1.html#combat-deep-dive) stop below the navbar,
   with room for the divider star */
.page-section[id] {
    scroll-margin-top: calc(var(--nav-height, 52px) + 48px);
}
/* Game pages: the "About the game" text the same size as the responsibilities list beside it */
.game-details .summary p {
    font-size: 0.9rem;
    line-height: 1.6;
}
/* A short subtitle right under a subheading (e.g. "Disrupt the ritual gone wrong"
   under "The Shard's Shadow"): smaller, italic and muted */
.page-section > .subheading-subtitle {
    margin: -0.2em 0 0.8em;
    font-size: 0.75rem;
    font-style: italic;
    opacity: 0.75;
}
/* Contribution cards: clicking anywhere on a card jumps down to its deep dive.
   The heading is the link, and its ::after is stretched over the whole card. */
.contribution {
    position: relative;
    transition: border-color 0.15s ease, background-color 0.15s ease;
}

.card-link {
    color: inherit;
    text-decoration: none;
}

.card-link::after {
    content: "";
    position: absolute;
    inset: 0;
}

.contribution:hover,
.contribution:focus-within {
    border-color: var(--color-nav);
    background: color-mix(in srgb, var(--color-text) 7%, transparent);
}

.card-link:focus-visible {
    outline: none; /* the whole card lights up instead (above) */
}
/* Links that jump within a page (e.g. the contribution cards) glide down instead of
   jumping. Visitors who've asked their system for less motion get the instant jump. */
@media (prefers-reduced-motion: no-preference) {
    html {
        scroll-behavior: smooth;
    }
}
/* A section that follows straight on from the one before, without the divider
   line and star above it (e.g. "Additional work" after "My contributions") */
.page-section.no-divider::before,
.page-section.no-divider::after,
.page-section.no-divider > h3::before {
    display: none;
}

.game-page .page-section.no-divider > h3 {
    padding-top: 0; /* no star above it to make room for */
}
/* A section's text with a picture beside it on the right (e.g. the fighter next to
   "Additional work"). On phones the picture goes under the text. */
.section-with-picture {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: 32px;
}

.section-picture {
    display: block;
    height: 380px;
    width: auto;
    margin-top: -80px; /* tall picture: let it rise up beside the heading, using the empty space */
    margin-bottom: 28px; /* keep its base clear of the divider below */
}

@media (max-width: 700px) {
    .section-with-picture {
        grid-template-columns: 1fr;
        justify-items: center;
    }

    .section-picture {
        height: 240px;
        margin-top: 0;
    }
}
/* Deep dives: readable line lengths, and smaller headings (h5) inside a deep dive,
   e.g. "Ice spikes" and "Boss logic" under Frost Jarl Ungarth */
.page-section > p,
.page-section > .ability-list {
    max-width: var(--reading-width);
}

.page-section > p + p {
    margin-top: 0.8em;
}

.page-section > h5 {
    margin: 1.8em 0 0.4em;
    font-family: var(--subtitle-font);
    font-size: 0.8rem;
    font-weight: normal;
    letter-spacing: 0.04em;
    color: var(--color-highlight);
}

/* "Themes: ..." line at the start of a deep dive */
.deep-dive-themes {
    font-size: 0.9rem;
}

.themes-label {
    font-weight: 700;
    color: var(--color-highlight);
}

/* "Second phase:" notes in the boss's ability list */
.phase-note {
    font-style: italic;
    opacity: 0.8;
}
/* "Additional boss fight features": each feature's text beside a picture */
.feature-row {
    display: grid;
    grid-template-columns: 1fr 220px;
    align-items: center;
    gap: 32px;
    max-width: var(--reading-width);
    margin-top: 20px;
}

.feature-row h6 {
    margin: 0 0 0.3em;
    font-family: var(--subtitle-font);
    font-size: 0.75rem;
    font-weight: normal;
    letter-spacing: 0.04em;
}

.feature-row p {
    margin: 0;
}

.feature-image {
    display: block;
    width: 100%;
    aspect-ratio: 1;
    object-fit: cover;
}

/* Where a picture will go: a plain square until one is added */
.image-slot {
    display: grid;
    place-items: center;
    aspect-ratio: 1;
    border: 1px solid color-mix(in srgb, var(--color-nav) 55%, transparent);
    background: color-mix(in srgb, var(--color-text) 8%, transparent);
    font-size: 0.7rem;
    color: color-mix(in srgb, var(--color-text) 60%, transparent);
}

@media (max-width: 700px) {
    .image-slot,
    .feature-image {
        width: min(100%, 260px);
    }
}

@media (max-width: 700px) {
    .feature-row {
        grid-template-columns: 1fr;
        gap: 14px;
    }
}
/* "Additional boss fight features" side by side, each with its text beside its picture */
.feature-pair {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 40px;
    margin-top: 16px;
}

/* each feature: a big picture across the full width of its column, its text underneath */
.feature-pair .feature-row {
    grid-template-columns: 1fr;
    align-items: start;
    gap: 12px;
    max-width: none;
    margin-top: 0;
}

.feature-pair .image-slot,
.feature-pair .feature-image {
    width: 100%;
    aspect-ratio: 16 / 10;
}

@media (max-width: 800px) {
    .feature-pair {
        grid-template-columns: 1fr;
        gap: 24px;
    }
}

/* Attack pictures (Battlemarked, Combat): one big picture, and the five attacks as
   small pictures in a row underneath. The selected one is outlined in rust. */
.attack-viewer {
    max-width: var(--reading-width); /* the same width as the paragraphs */
    margin-top: 20px;
}

.attack-main .image-slot,
.attack-main img {
    display: grid;
    place-items: center;
    width: 100%;
    aspect-ratio: 16 / 10;
    object-fit: cover;
}

.attack-main .image-slot {
    font-size: 0.85rem;
}

.attack-thumbs {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 10px;
    margin-top: 10px;
}

.attack-thumb {
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-align: center;
    cursor: pointer;
    opacity: 0.55;
    transition: opacity 0.15s ease;
}

.attack-thumb:hover,
.attack-thumb:focus-visible,
.attack-thumb.is-active {
    opacity: 1;
}

.attack-thumb .image-slot,
.attack-thumb img {
    display: grid;
    place-items: center;
    width: 100%;
    aspect-ratio: 16 / 10;
    object-fit: cover;
    font-size: 0.6rem;
    outline: 2px solid transparent;
    outline-offset: -2px;
}

.attack-thumb.is-active .image-slot,
.attack-thumb.is-active img {
    outline-color: var(--color-nav);
}

.attack-thumb-name {
    display: block;
    margin-top: 5px;
    font-size: 0.7rem;
}

.attack-thumb.is-active .attack-thumb-name {
    color: var(--color-highlight);
    font-weight: 700;
}

/* phones: five small pictures are too narrow for names under them */
@media (max-width: 600px) {
    .attack-thumbs {
        gap: 6px;
    }

    .attack-thumb-name {
        display: none;
    }
}
/* the selected attack's name and description, under the big picture */
.attack-caption {
    margin: 10px 0 0;
    font-size: 0.85rem;
}
/* arrows outside the big attack picture, one on each side of it. The caption and the
   row of small pictures are indented by the same amount, so they line up with the picture. */
.attack-viewer {
    --arrow-room: 52px;          /* an arrow (40px) plus the gap beside it (12px) */
    max-width: calc(var(--reading-width) + 2 * var(--arrow-room));
}

.attack-stage {
    display: flex;
    align-items: center;
    gap: 12px;
}

.attack-stage .attack-main {
    flex: 1;
    min-width: 0;
}

.attack-stage .attack-prev {
    order: -1;                   /* before the picture */
}

.attack-viewer .attack-caption,
.attack-viewer .attack-thumbs {
    margin-left: var(--arrow-room);
    margin-right: var(--arrow-room);
}

@media (max-width: 600px) {
    .attack-viewer {
        --arrow-room: 38px;
    }

    .attack-stage {
        gap: 6px;
    }

    .attack-stage .carousel-arrow {
        width: 32px;
        height: 32px;
    }
}
/* A section that only holds a link box (e.g. "Learn more" on the Spatial Ops page):
   generous space around it, so it stands apart from the content above */
.page-section.link-section {
    margin-top: 16px; /* plus the space every section leaves below itself */
    padding-bottom: 24px;
}

.link-section .link-box {
    margin-top: 16px;
}
/* Character gallery (Home Sports): a carousel of six cards (the "Updates" carousel:
   three at a time, one on phones), each with a square picture, the character's name,
   their sport and their planned superpower */
.character-carousel {
    margin-top: 12px;
}

.character-card {
    margin: 0;
}

.character-card figcaption {
    margin-top: 10px;
    font-size: 0.75rem;
    line-height: 1.5;
}

.character-name {
    display: block;
    margin-bottom: 2px;
    font-family: var(--subtitle-font);
    font-size: 0.9rem;
    letter-spacing: 0.04em;
}

.character-detail {
    display: block;
}

.character-label {
    font-weight: 700;
    color: var(--color-highlight);
}

/* the note under the character gallery */
.character-note {
    max-width: 36em;
    margin: 24px auto 0;          /* centred under the gallery */
    font-size: 0.7rem;
    font-style: italic;
    text-align: center;
    opacity: 0.85;
}

/* Game pages: space under every section, so its last line stays well clear of the
   next divider and the star's point */
.game-page .page-section {
    padding-bottom: 32px;
}

/* Character gallery: one character at a time, the picture on the left and their name,
   sport and superpower beside it on the right (stacked on phones) */
.character-track {
    --visible: 1;
}

.character-track .character-card {
    display: grid;
    grid-template-columns: minmax(0, 300px) 1fr;
    align-items: center;
    gap: 32px;
}

.character-track .character-card figcaption {
    margin-top: 0;
    font-size: 0.85rem;
    line-height: 1.6;
}

.character-track .character-name {
    margin-bottom: 8px;
    font-size: 1.3rem;
}

.character-track .character-detail + .character-detail {
    margin-top: 6px;
}

@media (max-width: 600px) {
    .character-track .character-card {
        grid-template-columns: 1fr;
        gap: 14px;
    }

    .character-track .character-name {
        font-size: 1.1rem;
    }
}
/* Battlemarked "Additional work": bigger text beside the fighter picture */
.section-with-picture .section-points {
    font-size: 0.95rem;
}
/* Deep dives: a picture with a caption under it, on its own or two side by side
   (e.g. "Gated progress" and "Familiar places" on the Battlemarked page) */
.deep-dive-figure {
    max-width: var(--reading-width);
    margin: 16px 0 0;
}

.deep-dive-figure .image-slot,
.deep-dive-figure .feature-image {
    width: 100%;
    aspect-ratio: 16 / 10;
}

.deep-dive-figure figcaption {
    margin-top: 8px;
    font-size: 0.75rem;
    font-style: italic;
    opacity: 0.85;
}

.figure-pair {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 24px;
    max-width: var(--reading-width);
}

.figure-pair .deep-dive-figure {
    margin-top: 16px;
}

@media (max-width: 600px) {
    .figure-pair {
        grid-template-columns: 1fr;
        gap: 0;
    }
}
/* two pictures side by side with one caption spanning both (stacked on phones) */
.figure-pair-images {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 24px;
}

@media (max-width: 600px) {
    .figure-pair-images {
        grid-template-columns: 1fr;
        gap: 12px;
    }
}
/* a short label under one picture of a pair (e.g. "Before" / "After") */
.figure-label {
    display: block;
    margin-top: 6px;
    font-size: 0.7rem;
    font-weight: 700;
    color: var(--color-highlight);
}
/* A paragraph with a picture beside it on the right (e.g. "Testbed for future
   content" on the Battlemarked page). On phones the picture goes under the text. */
.text-with-figure {
    display: grid;
    grid-template-columns: 1fr 360px;
    align-items: center;
    gap: 28px;
    max-width: var(--reading-width);
}

.text-with-figure p {
    margin: 0;
}

.text-with-figure .image-slot,
.text-with-figure .feature-image {
    width: 100%;
    aspect-ratio: 16 / 10;
}

@media (max-width: 600px) {
    .text-with-figure {
        grid-template-columns: 1fr;
        gap: 14px;
    }
}

/* Game pages: a short intro about my role, under "About the game" / "My responsibilities" */
.role-intro {
    margin-top: 36px;
    margin-bottom: 32px;   /* the same room before the next divider as under every section */
}

.role-intro p {
    max-width: var(--reading-width);
    font-size: 0.9rem;
    line-height: 1.6;
}

.role-intro p + p {
    margin-top: 0.8em;
}
/* Combat deep dive: the themes and intro text beside a picture of the boss
   (a cut-out with a transparent background). On phones the boss goes under the text. */
.boss-intro {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 32px;
}

.boss-intro-text > p:first-child {
    margin-top: 0;
}

.boss-portrait {
    display: block;
    height: 540px;
    width: auto;
}

@media (max-width: 700px) {
    .boss-intro {
        grid-template-columns: 1fr;
        justify-items: center;
        gap: 16px;
    }

    .boss-portrait {
        height: 280px;
    }
}
/* Combat deep dive intro: the boss's name, subtitle, themes and intro text sit in the
   column beside his picture, a little larger to fill the space, centred against him */
.boss-intro {
    margin-top: 1.2em;
}

.boss-intro-text > h4 {
    margin: 0 0 0.3em;
    font-family: var(--subtitle-font);
    font-size: 1.3rem;
    font-weight: normal;
    letter-spacing: 0.04em;
}

.boss-intro-text > .subheading-subtitle {
    margin: 0 0 1.4em;
    font-size: 0.9rem;
    font-style: italic;
    opacity: 0.75;
}

.boss-intro-text > .deep-dive-themes {
    font-size: 1rem;
}

.boss-intro-text > p:not([class]) {
    margin-top: 0.8em;
    font-size: 0.95rem;
    line-height: 1.65;
}
/* Combat deep dive: the themes line as a highlighted strip, a rust bar down its
   left edge and a faint fill, so it stands out from the paragraph under it */
.boss-intro-text > .deep-dive-themes {
    margin: 0;
    padding: 12px 16px;
    border-left: 3px solid var(--color-nav);
    background: color-mix(in srgb, var(--color-nav) 12%, transparent);
    font-size: 1.05rem;
    letter-spacing: 0.01em;
}

.boss-intro-text > .deep-dive-themes .themes-label {
    margin-right: 4px;
    font-family: var(--subtitle-font);
    font-weight: normal;
    letter-spacing: 0.04em;
}

.boss-intro-text > .deep-dive-themes + p {
    margin-top: 1.1em;
}
/* each theme on its own, with a small rust star between them (wraps whole themes,
   never in the middle of one) */
.deep-dive-themes .theme {
    white-space: nowrap;
}

.deep-dive-themes .theme + .theme::before {
    content: "\2726";
    display: inline-block;
    margin: 0 0.6em;
    font-size: 0.6em;
    vertical-align: 0.25em;
    color: var(--color-highlight);
}
/* each theme on its own line, with a small rust star in front; "Themes:" above them */
.deep-dive-themes .themes-label {
    display: block;
    margin-bottom: 4px;
}

.deep-dive-themes .theme {
    display: block;
}

.deep-dive-themes .theme::before,
.deep-dive-themes .theme + .theme::before {
    content: "\2726";
    display: inline-block;
    margin: 0 0.6em 0 0;
    font-size: 0.6em;
    vertical-align: 0.25em;
    color: var(--color-highlight);
}
/* the themes in a 2 x 2 grid, "Themes:" across the top */
.boss-intro-text > .deep-dive-themes {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 20px;
    row-gap: 4px;
}

.deep-dive-themes .themes-label {
    grid-column: 1 / -1;
}

.deep-dive-themes .theme {
    white-space: normal;   /* a long theme may wrap within its own cell */
}
@media (max-width: 600px) {
    .boss-intro-text > .deep-dive-themes {
        font-size: 0.85rem;
        column-gap: 12px;
    }
}
/* no star in front of the themes */
.deep-dive-themes .theme::before,
.deep-dive-themes .theme + .theme::before {
    content: none;
}
/* Narrative and Encounters deep dives: their text and pictures are a reading-width
   column (--reading-width), so centre that column in the page instead of leaving it
   against the left edge of the wider 960px area */
#narrative-deep-dive > *,
#encounters-deep-dive > * {
    max-width: var(--reading-width);
    margin-left: auto;
    margin-right: auto;
}
/* Combat deep dive: the same centred reading column as Narrative and Encounters.
   The boss intro (Ungarth beside his text) keeps the full width, and the attack
   picture viewer keeps the extra room for its arrows; both are centred too. */
#combat-deep-dive > * {
    max-width: var(--reading-width);
    margin-left: auto;
    margin-right: auto;
}

#combat-deep-dive > .boss-intro {
    max-width: none;
}

#combat-deep-dive > .attack-viewer {
    max-width: calc(var(--reading-width) + 2 * var(--arrow-room));
}
/* In-world story text in a deep dive (e.g. the "Narrative setting" of The Shard's
   Shadow): italic, with a thin rust line down the left like a quoted passage */
.page-section > .story-text {
    padding-left: 16px;
    border-left: 2px solid color-mix(in srgb, var(--color-nav) 70%, transparent);
    font-style: italic;
    line-height: 1.7;
    opacity: 0.9;
}

/* lists inside a deep dive sit a little closer to their heading */
#encounters-deep-dive > .section-points {
    margin-top: 0.2em;
}
/* two story paragraphs in a row read as one quoted passage: no gap in the line */
.page-section > .story-text + .story-text {
    margin-top: 0;
    padding-top: 0.8em;
}
.page-section > .story-text:has(+ .story-text) {
    margin-bottom: 0;
}
/* Narrative background inside the Jarl intro column: the same small heading and
   story-text style as elsewhere in the deep dives */
.boss-intro-text > h5 {
    margin: 0 0 0.4em;
    font-family: var(--subtitle-font);
    font-size: 0.8rem;
    font-weight: normal;
    letter-spacing: 0.04em;
    color: var(--color-highlight);
}

.boss-intro-text > .story-text {
    margin: 0;
    padding-left: 16px;
    border-left: 2px solid color-mix(in srgb, var(--color-nav) 70%, transparent);
    font-size: 0.85rem;
    font-style: italic;
    line-height: 1.7;
    opacity: 0.9;
}

.boss-intro-text > .story-text + .story-text {
    padding-top: 0.8em;
}

/* room between the story and the themes strip under it */
.boss-intro-text > .story-text + .deep-dive-themes {
    margin-top: 1.4em;
}
/* Combat: Ungarth's name and subtitle at the top keep their larger size */
#combat-deep-dive > h4 {
    margin: 0.4em auto 0.3em;
    font-size: 1.3rem;
}

#combat-deep-dive > h4 + .subheading-subtitle {
    margin-bottom: 1.4em;
    font-size: 0.9rem;
}

/* the themes + intro beside Ungarth: their text starts on the same left edge as the
   column above, and he takes the extra room on the right */
#combat-deep-dive > .boss-intro {
    margin-top: 1.6em;
    padding-left: max(0px, calc((100% - var(--reading-width)) / 2));
}
/* story text without the line down the left, lined up with the other text */
.page-section > .story-text,
.boss-intro-text > .story-text {
    padding-left: 0;
    border-left: none;
}
/* Deep dives: the example's name and subtitle centred under the section title, with
   some room in between, so title, name and subtitle read as one heading block */
#narrative-deep-dive > h4,
#encounters-deep-dive > h4,
#combat-deep-dive > h4,
#narrative-deep-dive > h4 + .subheading-subtitle,
#encounters-deep-dive > h4 + .subheading-subtitle,
#combat-deep-dive > h4 + .subheading-subtitle {
    text-align: center;
}

#narrative-deep-dive > h4,
#encounters-deep-dive > h4,
#combat-deep-dive > h4 {
    margin-top: 1.2em;
}

/* a little more room before the content under the heading block */
#narrative-deep-dive > h4 + .subheading-subtitle,
#encounters-deep-dive > h4 + .subheading-subtitle {
    margin-bottom: 1.2em;
}
/* Click-to-enlarge for screenshots on the game pages (script.js builds the viewer):
   the picture shown large over a dimmed page */
.zoomable {
    cursor: zoom-in;
}

.lightbox {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: none;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 14px;
    padding: 24px;
    background: rgb(5 5 23 / 0.92);
    cursor: zoom-out;
}

.lightbox.open {
    display: flex;
}

/* the dark background appears at once; only the picture fades in */
.lightbox.open img {
    animation: lightbox-in 0.2s ease;
}

@keyframes lightbox-in {
    from { opacity: 0; }
    to { opacity: 1; }
}

.lightbox img {
    display: block;
    max-width: min(1400px, 94vw);
    max-height: 82vh;
    width: auto;
    height: auto;
    object-fit: contain;
    box-shadow: 0 10px 40px rgb(0 0 0 / 0.6);
    cursor: default;
}

.lightbox-close {
    position: absolute;
    top: 16px;
    right: 16px;
    width: 40px;
    height: 40px;
    border: 2px solid #FAF3E5;
    border-radius: 50%;
    background: none;
    color: #FAF3E5;
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
    transition: transform 0.15s ease;
}

.lightbox-close:hover,
.lightbox-close:focus-visible {
    transform: scale(1.15);
}

@media (prefers-reduced-motion: reduce) {
    .lightbox.open img {
        animation: none;
    }
}
/* the enlarged view shows a clip the same way as a picture */
.lightbox video {
    display: block;
    max-width: min(1400px, 94vw);
    max-height: 82vh;
    width: auto;
    height: auto;
    box-shadow: 0 10px 40px rgb(0 0 0 / 0.6);
    cursor: default;
}

.lightbox video[hidden],
.lightbox img[hidden] {
    display: none;
}

/* the fog clip beside "Testbed": a widescreen frame that fits the video */
.text-with-figure .feature-video {
    aspect-ratio: 16 / 9;
    object-fit: cover;
}
/* arrows in the enlarged view, for pictures that sit together (a pair, or the boss attacks):
   at the sides of the screen, or under the picture on phones */
.lightbox .lightbox-prev,
.lightbox .lightbox-next {
    display: none;
    position: absolute;
    top: 50%;
    margin-top: -20px;
}

.lightbox.has-group .lightbox-prev,
.lightbox.has-group .lightbox-next {
    display: block;
}

.lightbox-prev {
    left: 16px;
}

.lightbox-next {
    right: 16px;
}

.lightbox.has-group img,
.lightbox.has-group video {
    max-width: min(1400px, calc(100vw - 144px));
}

@media (max-width: 600px) {
    .lightbox .lightbox-prev,
    .lightbox .lightbox-next {
        top: auto;
        bottom: 20px;
        margin-top: 0;
    }

    .lightbox-prev {
        left: calc(50% - 56px);
    }

    .lightbox-next {
        right: calc(50% - 56px);
    }

    .lightbox.has-group img,
    .lightbox.has-group video {
        max-width: 94vw;
        max-height: 74vh;
    }
}
/* an attack with no picture yet: its placeholder box, shown large with the attack name */
.lightbox .lightbox-slot {
    width: min(1000px, calc(100vw - 144px));
    max-height: 74vh;
    aspect-ratio: 16 / 10;
    border-color: rgb(250 243 229 / 0.4);
    background: rgb(250 243 229 / 0.06);
    color: rgb(250 243 229 / 0.75);
    font-size: 1.4rem;
    cursor: default;
    animation: lightbox-in 0.2s ease;
}

.lightbox .lightbox-slot[hidden] {
    display: none;
}

@media (max-width: 600px) {
    .lightbox .lightbox-slot {
        width: 94vw;
        font-size: 1.1rem;
    }
}

@media (prefers-reduced-motion: reduce) {
    .lightbox .lightbox-slot {
        animation: none;
    }
}
/* several paragraphs beside a picture (e.g. "Gameplay goal"): the usual space between them */
.text-with-figure-text p + p {
    margin-top: 1em;
}
/* a wide clip on its own under the text (e.g. the warlock introduction): widescreen, not 16:10 */
.deep-dive-figure .feature-video {
    aspect-ratio: 16 / 9;
    object-fit: cover;
}
/* a link inside running text (e.g. Jerry Holkins on the Battlemarked page):
   keeps the text's own colour, with a thin underline that thickens on hover */
.text-link {
    color: inherit;
    text-decoration: underline;
    text-decoration-color: var(--color-highlight);
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
}

.text-link:hover,
.text-link:focus-visible {
    text-decoration-thickness: 2px;
}
/* the caption under the enlarged picture: the text that sits under it on the page */
.lightbox-caption {
    max-width: min(760px, 94vw);
    margin: 0;
    font-size: 0.95rem;
    line-height: 1.5;
    text-align: center;
    color: #FAF3E5;
    cursor: default;
}

.lightbox-caption[hidden] {
    display: none;
}

.lightbox-caption .highlight {
    color: #E0583E;
}

@media (max-width: 600px) {
    .lightbox-caption {
        font-size: 0.85rem;
    }
}
/* About Me: the photo at its own shape (not cropped to a square); on phones,
   where it sits above the text, it's kept to a sensible size */
.about .portrait {
    aspect-ratio: auto;
}

.about .portrait img {
    height: auto;
}

@media (max-width: 700px) {
    .about .portrait {
        max-width: 360px;
        width: 100%;
        justify-self: center;
    }
}
/* About Me: the photo at the left, up to 340px wide */
.about .portrait {
    max-width: 340px;
    width: 100%;
}
.about .portrait {
    align-self: start;
}
/* side by side on wide screens, the photo's column is exactly as wide as the photo; the text gets the rest
   (on medium screens it keeps the narrower one-third column, so the text has room) */
@media (min-width: 901px) {
    .about {
        grid-template-columns: minmax(0, 340px) minmax(0, 1fr);
    }
}
/* About Me: the big bold "Resume" link under the photo (opens the PDF in a new tab) */
.resume-link {
    display: block;
    margin-top: 0;
    text-align: center;
    font-family: var(--subtitle-font); /* Metamorphous, like the subtitles */
    font-size: 1.6rem;
    font-weight: 400;
    color: var(--color-highlight);
    text-decoration: none;
}
/* Small phones: with Resume in the navbar, everything a little tighter so it stays on one row */
@media (max-width: 400px) {
    nav {
        gap: 6px;
    }

    nav ul {
        gap: 5px;
    }

    nav > ul > li > a,
    nav .dropdown-toggle {
        font-size: 0.78rem;
        padding-left: 1px;
        padding-right: 1px;
        letter-spacing: 0.01em;
    }

    .nav-icon {
        width: 34px;
        height: 34px;
    }
}
/* The narrowest phones (under 350px) */
@media (max-width: 350px) {
    nav > ul > li > a,
    nav .dropdown-toggle {
        font-size: 0.7rem;
    }

    .nav-icon {
        width: 30px;
        height: 30px;
    }
}
/* the line between the photo and "Resume": rust, tapering to points at both ends like the dividers */
.portrait .resume-link::before {
    content: "";
    display: block;
    height: 3px;
    margin: 18px 0 28px;
    background: var(--color-highlight);
    clip-path: polygon(0 50%, 40px 0, calc(100% - 40px) 0, 100% 50%, calc(100% - 40px) 100%, 40px 100%);
}/* the intro paragraphs at the top of a game page: centred, like the deep dives' text */
.role-intro p {
    margin-left: auto;
    margin-right: auto;
}
/* Game pages: the "My contributions" cards and the "Additional work" bullets with their
   picture use the same centred width as the rest of the text */
.game-page .contribution-columns,
.game-page .section-with-picture {
    max-width: var(--reading-width);
    margin-left: auto;
    margin-right: auto;
}
/* Spatial Ops and Home Sports: the "My contributions" bullet list, the same centred width */
.game-page .page-section > .section-points {
    max-width: var(--reading-width);
    margin-left: auto;
    margin-right: auto;
}
/* "The True Heroes": the team photos side by side. Each takes room in proportion to its
   shape (--ratio, width / height), so both end up the same height with nothing cropped. */
.team-photos {
    display: flex;
    gap: 12px;
}

.team-photos .feature-image {
    flex: var(--ratio) 1 0;
    min-width: 0;
    aspect-ratio: auto;
    height: auto;
    object-fit: contain;
}

@media (max-width: 600px) {
    .team-photos {
        flex-direction: column;
        gap: 12px;
    }

    .team-photos .feature-image {
        flex: none;
        width: 100%; /* the full screen width, not the smaller size other pictures get on phones */
    }
}
/* "The True Heroes": the text centred, the team photos under it (a bit narrower than the text) */
.closing-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
    gap: 20px;
    max-width: var(--reading-width);
    margin: 16px auto 0;
}

.closing-row p {
    margin: 0;
    text-align: center;
}

.closing-row .team-photos {
    width: 100%;
    max-width: 680px;
}
/* "Resume" under the photo: an arrow on each side pointing at it; on hover they move in closer */
.resume-text {
    display: inline-flex;
    align-items: center;
    gap: 14px;
}

.resume-text::before,
.resume-text::after {
    content: "";
    width: 11px;
    height: 11px;
    border-top: 3px solid currentColor;
    border-right: 3px solid currentColor;
    border-radius: 1px;
    transition: translate 0.2s ease;
}

/* the left arrow points right, the right arrow points left */
.resume-text::before {
    transform: rotate(45deg);
}

.resume-text::after {
    transform: rotate(-135deg);
}

.resume-link:hover .resume-text::before,
.resume-link:focus-visible .resume-text::before {
    translate: 6px 0;
}

.resume-link:hover .resume-text::after,
.resume-link:focus-visible .resume-text::after {
    translate: -6px 0;
}

@media (prefers-reduced-motion: reduce) {
    .resume-text::before,
    .resume-text::after {
        transition: none;
    }
}
/* a space for a big gif/clip: widescreen, like the clips it will hold */
.deep-dive-figure.gif-slot .image-slot {
    aspect-ratio: 16 / 9;
}
/* Game pages: more room around each divider line: under the end of a section, and between
   the star and the next section's title */
.game-page .page-section,
.game-page .game-updates {
    padding-bottom: 48px;
}

.game-page .page-section > h3,
.game-page .game-updates > h3 {
    padding-top: 24px;
}

/* the last section ends at the footer's own divider, so it keeps its usual space */
.game-page .page-section:last-child {
    padding-bottom: 32px;
}
/* Deep dives: more space before each smaller heading (e.g. "Familiar Places"),
   so the parts of a deep dive stand apart from each other */
.page-section > h5 {
    margin-top: 3em;
}
/* About Me: more room between the "About Me" title and the photo and text below it */
.about-page .page-title {
    margin-bottom: 32px;
}

@media (max-width: 700px) {
    .about-page .page-title {
        margin-bottom: 16px;
    }
}
/* Boss attack diagrams: shown at their own shape (7:5), so nothing in them is cropped */
.attack-main .image-slot,
.attack-main img,
.attack-thumb .image-slot,
.attack-thumb img {
    aspect-ratio: 7 / 5;
}