/**
 * Home page layout, plus one site-wide chrome correction.
 * =======================================================
 *
 * Most of this file is the home page. The exception is the "Page chrome"
 * section below, which applies everywhere: it has to load after
 * glass-standard.css to outweigh an !important there, and this is the last
 * stylesheet the page pulls in. If this file is ever renamed or reordered,
 * that rule has to move with it or the theme strip goes back to being a card
 * on every page.
 *
 * The page used to be a single column of seven identically-sized article
 * blocks, alternating dark and light. Everything had the same weight, so
 * nothing led: a visitor landed on a devlog feed with no idea whose site it
 * was or what the work looked like.
 *
 * This gives it an order to read in - who, then the work, then the writing -
 * and a grid to sit on. It changes no colours, fonts or surfaces: the ramp
 * (--re-brand-*), the three faces (ThaleahFat display, Silkscreen UI, Albert
 * Sans body) and the glass tokens are all the existing ones. What changes is
 * scale, spacing and placement.
 *
 * Type roles, kept consistent throughout:
 *   Silkscreen   small caps labels only - eyebrows, meta, stat keys. A pixel
 *                face reads as craft at 9-11px and as noise at paragraph
 *                size, so it never sets running text here.
 *   ThaleahFat   display headings only.
 *   Albert Sans  everything a person actually reads.
 */

/* ------------------------------------------------------------------ *
 * Visibility
 * ------------------------------------------------------------------ */

/*
 * Nothing on this page may depend on JavaScript to become visible.
 *
 * The first version of this layout carried AOS scroll animations, and on the
 * live page all nine panels stayed at opacity 0 with a 100px offset - the
 * hero included, which had even been given the .aos-animate class and still
 * never resolved. The page was fully built, images loaded, text in place,
 * and completely invisible.
 *
 * The attributes are gone from the markup, but AOS's stylesheet still ships
 * site-wide and matches on [data-aos]. This makes sure that if one is ever
 * pasted back in here - or another library reaches in - the content is shown
 * regardless. An entrance animation is worth nothing next to the risk of a
 * blank homepage.
 */
.home [data-aos] {
    opacity: 1 !important;
    transform: none !important;
    visibility: visible !important;
}

/* ------------------------------------------------------------------ *
 * Page chrome - site wide
 * ------------------------------------------------------------------ */

/*
 * The theme/account strip was a full glass card: filled, bordered, rounded,
 * with a 32px drop shadow. It is a utility bar - theme toggle, account,
 * language - and at that weight it read as the first content on every page,
 * competing with whatever the page was actually about.
 *
 * It now keeps a single hairline and nothing else. This applies to every
 * page, not just the home page: the first pass scoped it to the home page
 * and that left the site inconsistent with itself, the chrome changing
 * shape as you moved between pages.
 *
 * It lives in this stylesheet rather than header-controls-panel.css because
 * glass-standard.css applies the card treatment with !important, and this is
 * the last stylesheet the page loads - the only place a rule is guaranteed
 * to outweigh it.
 */
.header-controls-panel {
    /*
     * !important throughout: glass-standard.css applies the fill, blur and
     * border to this panel with !important, and a mobile block in
     * header-controls-panel.css re-adds the backdrop filter. This file loads
     * after both, so matching their weight is the only way to win.
     */
    background: transparent !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    border: none !important;
    border-bottom: 1px solid rgba(130, 107, 125, 0.18) !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    padding: 10px 4px;
    margin-top: 8px;
    margin-bottom: 0;
}

/* The card's noise and sheen overlays go with it. */
.header-controls-panel::before,
.header-controls-panel::after {
    display: none;
}

/* ------------------------------------------------------------------ *
 * Rhythm
 * ------------------------------------------------------------------ */

.home {
    /* One spacing scale for the whole page, so sections relate instead of
       each carrying its own arbitrary margin. */
    --home-max: 1180px;
    --home-section: clamp(56px, 8vw, 112px);
    --home-block: clamp(24px, 3vw, 40px);
    /*
     * The hairline is defined on :root in theme-tokens.css now, so this local
     * copy is redundant - it is kept only so the home page still has a rule
     * colour if that file is ever loaded without this one. Same value.
     */
    --home-rule: color-mix(in srgb, var(--re-brand-400) 22%, transparent);

    max-width: var(--home-max);
    margin: 0 auto;
    padding: 0 24px;
}

.home-section {
    margin-bottom: var(--home-section);
}

.home-section:last-child {
    margin-bottom: 0;
}

/* A section header: pixel eyebrow, display title, hairline. */
.home-eyebrow {
    font-family: var(--re-font-ui);
    font-size: 9px;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--re-brand-300);
    opacity: 0.85;
    margin: 0 0 10px;
    display: block;
}

.home-section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 24px;
    flex-wrap: wrap;
    margin-bottom: var(--home-block);
    padding-bottom: 14px;
    border-bottom: 1px solid var(--home-rule);
}

.home-section-title {
    font-family: var(--re-font-display);
    font-size: clamp(1.5rem, 3vw, 2.1rem);
    letter-spacing: 0.02em;
    color: var(--re-text-color);
    margin: 0;
    line-height: 1.1;
}

.home-section-link {
    font-family: var(--re-font-ui);
    font-size: 9px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--re-brand-300);
    text-decoration: none;
    white-space: nowrap;
    transition: color 0.25s ease, transform 0.25s ease;
}

.home-section-link:hover {
    color: var(--re-text-color);
    transform: translateX(3px);
}

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

.home-hero {
    padding: clamp(40px, 7vw, 96px) 0 var(--home-section);
    /* Asymmetric on purpose: the statement gets the room, the portrait sits
       beside it and the numbers in the margin, rather than any of the three
       competing for the centre. */
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    gap: clamp(24px, 4vw, 48px);
    /* Top, not centre. The identity column runs several hundred pixels tall,
       so centring floats the portrait down beside the body copy and away
       from the name it belongs to. Aligned to the start the three columns
       read as one masthead. */
    align-items: start;
}

/*
 * The portrait: 48x48 pixel art, so it may only ever be drawn at a whole
 * multiple of its own size.
 *
 * 144px is 3x exactly. Anything between the multiples - a percentage, a vw
 * unit, a clamp() - puts source pixels on fractional screen pixels and the
 * browser blends them, which is what turns pixel art to mush. The size is
 * therefore stated in fixed px at each breakpoint and never interpolated.
 *
 * image-rendering: pixelated is what stops the upscale being smoothed. The
 * two lines above it are the older spellings, kept for Firefox and Safari
 * versions that never took the standard keyword.
 */
.home-avatar {
    width: 144px;
    height: 144px;
    display: block;
    image-rendering: -moz-crisp-edges;
    image-rendering: -webkit-optimize-contrast;
    image-rendering: pixelated;
    /* A drop-shadow rather than a box-shadow: it follows the alpha edge of
       the sprite instead of drawing a rectangle behind it, so the art keeps
       its silhouette against the moving background. */
    filter: drop-shadow(0 4px 14px rgba(0, 0, 0, 0.55));
    /* Optical, not mathematical: drops the sprite so its top edge sits level
       with the eyebrow's cap height rather than with its line box. */
    margin-top: 4px;
}

.home-hero-name {
    font-family: var(--re-font-display);
    font-size: clamp(2.8rem, 9vw, 5.5rem);
    line-height: 0.95;
    letter-spacing: 0.01em;
    margin: 0 0 20px;
    color: var(--re-text-color);
    /* The background art sits directly behind this, so the type needs its
       own weight against a moving field. */
    text-shadow: 0 2px 24px rgba(0, 0, 0, 0.55);
}

.home-hero-lead {
    font-family: var(--re-font-body);
    font-size: clamp(1.05rem, 1.6vw, 1.35rem);
    line-height: 1.55;
    color: var(--re-text-color);
    opacity: 0.9;
    max-width: 34ch;
    margin: 0 0 14px;
}

.home-hero-aside {
    font-family: var(--re-font-body);
    font-size: 0.95rem;
    line-height: 1.6;
    color: var(--re-text-color);
    opacity: 0.55;
    max-width: 40ch;
    margin: 0 0 32px;
}

.home-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
}

.home-btn {
    font-family: var(--re-font-ui);
    font-size: 9px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    padding: 13px 22px;
    border-radius: var(--re-radius-sm);
    text-decoration: none;
    border: 1px solid var(--re-border);
    color: var(--re-text-color);
    background: var(--re-surface);
    backdrop-filter: blur(10px) saturate(1.4);
    -webkit-backdrop-filter: blur(10px) saturate(1.4);
    transition: transform 0.25s ease, border-color 0.25s ease, background 0.25s ease;
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.home-btn:hover {
    transform: translateY(-2px);
    border-color: var(--re-brand-300);
    color: var(--re-text-color);
}

.home-btn-primary {
    background: linear-gradient(135deg, var(--re-brand-500) 0%, var(--re-brand-700) 100%);
    border-color: transparent;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
}

/* The stat rail: keys in pixel type, values in the display face. */
.home-stats {
    display: grid;
    gap: 22px;
    padding-left: clamp(20px, 3vw, 36px);
    border-left: 1px solid var(--home-rule);
}

.home-stat-value {
    font-family: var(--re-font-display);
    font-size: clamp(1.6rem, 3vw, 2.4rem);
    line-height: 1;
    color: var(--re-text-color);
    display: block;
}

.home-stat-key {
    font-family: var(--re-font-ui);
    font-size: 8px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--re-brand-300);
    opacity: 0.8;
    margin-top: 6px;
    display: block;
}

/* ------------------------------------------------------------------ *
 * Featured work
 * ------------------------------------------------------------------ */

.home-feature {
    display: grid;
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
    gap: clamp(20px, 3vw, 40px);
    align-items: center;
    margin-bottom: var(--home-block);
}

.home-feature-media,
.home-card-media {
    position: relative;
    overflow: hidden;
    border-radius: var(--re-radius-lg);
    border: 1px solid var(--re-border);
    background: var(--re-surface-sunken);
    aspect-ratio: 16 / 10;
}

.home-feature-media img,
.home-card-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.6s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.home-feature:hover .home-feature-media img,
.home-card:hover .home-card-media img {
    transform: scale(1.04);
}

/* Nothing uploaded yet: a quiet placeholder rather than a broken frame. */
.home-media-empty {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--re-font-ui);
    font-size: 9px;
    letter-spacing: 0.16em;
    color: var(--re-brand-300);
    opacity: 0.4;
}

.home-feature-title {
    font-family: var(--re-font-display);
    /* !important for the same reason as the card title: h3's 1.6rem in
       theme-color-fix.css was capping this clamp at its own minimum. */
    font-size: clamp(1.6rem, 3.4vw, 2.6rem) !important;
    line-height: 1.05;
    margin: 12px 0 14px;
    color: var(--re-text-color);
}

.home-feature-title a,
.home-card-title a {
    color: inherit;
    text-decoration: none;
}

.home-feature-title a:hover,
.home-card-title a:hover {
    color: var(--re-brand-300);
}

.home-feature-desc {
    font-family: var(--re-font-body);
    font-size: 1rem;
    line-height: 1.65;
    color: var(--re-text-color);
    opacity: 0.75;
    margin: 0 0 20px;
}

/* ------------------------------------------------------------------ *
 * Work grid
 * ------------------------------------------------------------------ */

.home-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: clamp(18px, 2.4vw, 28px);
}

.home-card {
    display: flex;
    flex-direction: column;
    gap: 12px;
    text-decoration: none;
    transition: transform 0.3s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.home-card:hover {
    transform: translateY(-4px);
}

.home-card-title {
    /*
     * The display face, taken from theme-color-fix.css's h1-h6 rule by not
     * overriding it - which also brings font-weight:normal and switches
     * antialiasing off, both of which a pixel face needs.
     *
     * The size has to be !important, and that is not a preference: the same
     * file sets `h3 { font-size: 1.6rem !important }`, which was quietly
     * winning over the 1.02rem this rule used to ask for. Card and feature
     * titles were both landing on 25.6px and only differed by face. Now that
     * they share a face, the sizes have to do the separating.
     */
    font-size: clamp(1.15rem, 1.5vw, 1.35rem) !important;
    line-height: 1.25;
    letter-spacing: 0.01em;
    color: var(--re-text-color);
    margin: 0;
}

.home-card-desc {
    font-family: var(--re-font-body);
    font-size: 0.88rem;
    line-height: 1.55;
    color: var(--re-text-color);
    opacity: 0.62;
    margin: 0;
}

/* Meta line shared by features and cards. */
.home-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    font-family: var(--re-font-ui);
    font-size: 8px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--re-brand-300);
    opacity: 0.9;
}

.home-meta-dot {
    width: 3px;
    height: 3px;
    border-radius: 50%;
    background: currentColor;
    opacity: 0.6;
}

.home-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 4px;
}

.home-tag {
    /*
     * Body face, not the pixel one. Silkscreen has no glyph for '#', so a
     * tag reading "C#" came out as "C" followed by a missing-character box -
     * on a portfolio where C# and C++ are the point. Symbols are exactly
     * what tech tags are full of, so they get a font that has them. The
     * pixel face is kept for meta and eyebrows, which are plain words.
     */
    font-family: var(--re-font-body);
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding: 5px 10px;
    border-radius: var(--re-radius-pill);
    border: 1px solid var(--re-border);
    color: var(--re-text-color);
    opacity: 0.7;
}

/* ------------------------------------------------------------------ *
 * Devlog
 * ------------------------------------------------------------------ */

.home-posts {
    display: grid;
    gap: 2px;
}

/*
 * Rows, not cards. Seven glass panels stacked down the page was the old
 * layout's main problem: writing is secondary to the work here, so it gets
 * a dense readable list and the work keeps the visual weight.
 */
.home-post {
    display: grid;
    grid-template-columns: 92px minmax(0, 1fr) auto;
    gap: clamp(16px, 2.5vw, 32px);
    align-items: baseline;
    padding: 22px 16px;
    border-bottom: 1px solid var(--home-rule);
    text-decoration: none;
    border-radius: var(--re-radius-sm);
    transition: background 0.25s ease, padding-left 0.25s ease;
}

.home-post:hover {
    background: rgba(130, 107, 125, 0.08);
    padding-left: 24px;
}

.home-post-date {
    font-family: var(--re-font-ui);
    font-size: 8px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--re-brand-300);
    opacity: 0.8;
    white-space: nowrap;
}

.home-post-title {
    /*
     * The display face, deliberately - and by NOT overriding it.
     *
     * theme-color-fix.css puts ThaleahFat on every h1-h6 with !important, so
     * this rule only has to stay out of the way. That matters beyond the font
     * name: the same declaration turns font-weight down to normal and switches
     * antialiasing off, and a pixel face needs both. Setting font-family here
     * instead would take the face and leave the smearing.
     *
     * Larger than the body-face version it replaces. ThaleahFat carries much
     * less ink per em, so matching the old 1.05rem by the number would have
     * read a size smaller than the excerpt beneath it.
     */
    font-size: clamp(1.15rem, 1.7vw, 1.4rem);
    line-height: 1.2;
    letter-spacing: 0.01em;
    color: var(--re-text-color);
    margin: 0 0 8px;
}

.home-post-excerpt {
    font-family: var(--re-font-body);
    font-size: 0.88rem;
    line-height: 1.55;
    color: var(--re-text-color);
    opacity: 0.6;
    margin: 0;
}

.home-post-cat {
    font-family: var(--re-font-ui);
    font-size: 8px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--re-brand-300);
    opacity: 0.7;
    white-space: nowrap;
}

/* ------------------------------------------------------------------ *
 * Closing call to action
 * ------------------------------------------------------------------ */

.home-cta {
    text-align: center;
    padding: clamp(40px, 6vw, 72px) 24px;
    border: 1px solid var(--re-border);
    border-radius: var(--re-radius-lg);
    background: var(--re-surface);
    backdrop-filter: blur(12px) saturate(1.5);
    -webkit-backdrop-filter: blur(12px) saturate(1.5);
}

.home-cta-title {
    font-family: var(--re-font-display);
    font-size: clamp(1.5rem, 3.4vw, 2.4rem);
    margin: 0 0 12px;
    color: var(--re-text-color);
}

.home-cta-text {
    font-family: var(--re-font-body);
    font-size: 1rem;
    line-height: 1.6;
    color: var(--re-text-color);
    opacity: 0.7;
    margin: 0 auto 26px;
    max-width: 48ch;
}

.home-cta .home-actions {
    justify-content: center;
}

/* ------------------------------------------------------------------ *
 * Narrow screens
 * ------------------------------------------------------------------ */

@media (max-width: 900px) {
    .home-feature {
        grid-template-columns: minmax(0, 1fr);
    }
}

@media (max-width: 768px) {
    .home {
        padding: 0 16px;
    }

    /* One column. At 375px there is no room for a portrait beside a name set
       at 9vw, and the two-column version centred the sprite against a 700px
       block, stranding it level with the body copy instead of the name.
       Stacked, the order reads portrait, name, copy, numbers. */
    .home-hero {
        grid-template-columns: minmax(0, 1fr);
        gap: 20px;
    }

    /* 96px is 2x - still a whole multiple, so still crisp. */
    .home-avatar {
        width: 96px;
        height: 96px;
        margin-top: 0;
    }

    .home-stats {
        grid-auto-flow: column;
        justify-content: start;
        gap: 28px;
        padding-left: 0;
        padding-top: 20px;
        border-left: none;
        border-top: 1px solid var(--home-rule);
    }

    /* Date above the title rather than a column that steals half the width. */
    .home-post {
        grid-template-columns: minmax(0, 1fr);
        gap: 8px;
        padding: 18px 12px;
    }

    .home-post:hover {
        padding-left: 16px;
    }

    .home-post-cat {
        justify-self: start;
    }
}

@media (prefers-reduced-motion: reduce) {
    .home-card,
    .home-post,
    .home-btn,
    .home-feature-media img,
    .home-card-media img {
        transition: none;
    }
}

/* ------------------------------------------------------------------ *
 * Platform marks
 * ------------------------------------------------------------------ */

/*
 * The consoles a piece shipped on, drawn as their own wordmarks. The base
 * styling lives in page-refined.css; these two rules only size them for the
 * places they appear on this page.
 *
 * Sized by height and never by width - the marks range from 2.4:1 (Xbox
 * Series) to 7:1 (Nintendo DS), so a common width would render one tiny and
 * another enormous. A shared height is what makes a mixed row read as one set.
 *
 * Both sit under a hairline with clear space above and below. On the portfolio
 * cards these marks originally butted straight against the buttons beneath
 * them, and 12px white logos with nothing between them and a control read as
 * overlapping it.
 */

/*
 * Written as .platform-badges.home-* rather than .home-* alone, and that is
 * not decoration.
 *
 * The base rule lives in page-refined.css:
 *
 *     .platform-badges { margin: 14px 0 0; padding: 0; }
 *
 * and page-refined.css loads AFTER this file. As single-class selectors the
 * two weigh the same, so the later one won: the padding-top set here resolved
 * to 0 and the wordmarks ended up 1px under their own separator, hard against
 * the line.
 *
 * Compounding the classes makes these (0,2,0) against the base's (0,1,0), so
 * they win on specificity and load order stops mattering. Reordering the
 * stylesheets would also have fixed it, and broken something else - that order
 * is what lets page-refined.css correct the pages it is responsible for.
 */

.platform-badges.home-card-platforms {
    margin-top: 12px;
    padding-top: 14px;
    border-top: 1px solid var(--home-rule);
    gap: 7px 12px;
}

.platform-badges.home-card-platforms .platform-badge img {
    height: 11px;
    max-width: 84px;
    opacity: 0.6;
}

.home-card:hover .platform-badges.home-card-platforms .platform-badge img {
    opacity: 0.85;
}

/* The one feature card gets room to breathe. */
.platform-badges.home-feature-platforms {
    margin-top: 20px;
    padding-top: 18px;
    border-top: 1px solid var(--home-rule);
    gap: 10px 20px;
}

.platform-badges.home-feature-platforms .platform-badge img {
    height: 16px;
    max-width: 120px;
    opacity: 0.72;
}

.platform-badges.home-feature-platforms .platform-badge img:hover {
    opacity: 1;
}

@media (max-width: 768px) {
    .platform-badges.home-feature-platforms .platform-badge img {
        height: 14px;
        max-width: 104px;
    }
}
