/* ================================================================
   NUTMEGGSY FAN WEBSITE — style.css
   ================================================================

   HOW TO READ CSS:
   CSS (Cascading Style Sheets) describes HOW HTML elements look.
   The basic pattern is:

       selector {
           property: value;
       }

   The "selector" targets HTML elements.
   The "property: value" pairs set the visual rules.

   HOW THIS FILE IS ORGANISED:
   ─────────────────────────────────────────────
   01. CSS Variables  (colour palette & fonts)
   02. Reset & Base   (clearing browser defaults)
   03. Typography     (heading styles)
   04. Buttons        (shared button styles)
   05. Navbar         (sticky top navigation)
   06. Hero           (full-screen welcome section)
   07. Sections       (shared padding & containers)
   08. About          (RPG character card)
   09. Schedule       (7-day stream grid)
   10. Stream         (Twitch embed layout)
   11. NutDex         (TCG placeholder card)
   12. Community      (cards + sub info)
   13. Setup          (gear list card)
   14. Footer
   15. Animations     (fade-in & keyframes)
   16. Responsive     (mobile overrides)
   ─────────────────────────────────────────────
================================================================ */


/* ================================================================
   01. CSS CUSTOM PROPERTIES (VARIABLES)
   ================================================================
   CSS variables are like named paint pots. We define them ONCE
   here and reference them throughout the file using var(--name).
   This means changing a colour is a single edit, not hunting
   through hundreds of lines.

   They live inside :root — the root of the entire document —
   so they're available everywhere.
================================================================ */
:root {

    /* ── BACKGROUND COLOURS ──────────────────────────────────── */
    /*
        Wood grain palette — base colours have green undertones that
        blend with warm amber grain lines applied via background-image.
        The result feels like aged timber: dark forest wood with
        amber candlelight playing across the grain.

        These are the BASE (fallback) colours; the actual rendered
        backgrounds use multi-layer gradients defined on body,
        .section-alt, and card selectors below.
    */
    --bg-dark:    #1a1a0e;   /* Dark olive-brown — base for the page background */
    --bg-card:    #241a08;   /* Darker warm brown — base for card surfaces */
    --bg-section: #1e1e12;   /* Olive-dark — base for alternate sections */

    /* ── WOOD ACCENT TONES ───────────────────────────────────── */
    --green-deep: #2a1f0a;   /* Dark warm brown — used in card art gradients */
    --green-mid:  #4a7c4a;   /* Mid forest green — kept for verified stamps */

    /* ── WARM / CANDLELIGHT TONES ────────────────────────────── */
    --amber: #d4821a;        /* Warm amber — live glows, card labels, borders */
    --gold:  #f0a500;        /* Bright candlelight gold — headings, highlights */

    /* ── TEXT COLOURS ────────────────────────────────────────── */
    --cream:  #f5e6c8;       /* Warm cream — primary text, like old parchment */
    --muted:  #a89070;       /* Muted warm brown — secondary text, descriptions */

    /* ── UI DETAILS ──────────────────────────────────────────── */
    --border: #3a2a10;       /* Dark amber-brown border — like a wood grain line */

    /* ── FONTS ───────────────────────────────────────────────── */
    --font-heading: 'Merriweather', Georgia, serif;
    /* Merriweather = cosy old-book serif. Falls back to Georgia if it fails to load. */

    --font-body: 'Inter', system-ui, sans-serif;
    /* Inter = clean modern sans-serif. system-ui = the OS's built-in font. */

    /* ── SPACING SCALE ───────────────────────────────────────── */
    /* rem = relative to the root font size (16px by default) */
    --space-xs: 0.25rem;   /*  4px */
    --space-sm: 0.5rem;    /*  8px */
    --space-md: 1rem;      /* 16px */
    --space-lg: 2rem;      /* 32px */
    --space-xl: 4rem;      /* 64px */

    /* ── BORDER RADIUS ───────────────────────────────────────── */
    --radius-sm: 4px;
    --radius-md: 8px;
    --radius-lg: 16px;
}


/* ================================================================
   02. RESET & BASE STYLES
   ================================================================
   Every browser (Chrome, Firefox, Safari, Edge) has its own
   built-in default styles — different margins, paddings,
   font sizes, etc. We "reset" these so our design looks
   consistent everywhere.
================================================================ */

/* The * selector targets EVERY element on the page */
*,
*::before,   /* ::before is a "pseudo-element" — like an invisible extra element BEFORE */
*::after {   /* ::after  is a "pseudo-element" — an invisible element AFTER */
    /*
        box-sizing: border-box — changes how width/height are calculated.
        DEFAULT (content-box): width = content only. Padding & border ADD to it.
        BORDER-BOX:            width = content + padding + border combined.
        Border-box is much easier to reason about, so we always set it globally.
    */
    box-sizing: border-box;

    /* Remove all default margins and padding so we start from zero */
    margin: 0;
    padding: 0;
}

html {
    /*
        scroll-behavior: smooth
        Makes anchor links (#section-id) scroll smoothly instead of jumping.
        We also implement this in JS for broader browser support.
    */
    scroll-behavior: smooth;

    /* Prevent a horizontal scrollbar appearing if something overflows slightly */
    overflow-x: hidden;
}

body {
    /*
        WOOD GRAIN BACKGROUND TECHNIQUE
        ════════════════════════════════════════════════════════════════
        CSS background-image accepts multiple layers, separated by commas.
        The FIRST layer listed is on TOP; the LAST layer is at the bottom.
        They're all transparent (via rgba or transparent keywords), so
        each layer adds its effect on top of the one below.

        HOW EACH LAYER WORKS:
        ─────────────────────
        Layer 1 (top): repeating-linear-gradient at 90°
          → Tight 4px vertical stripes: 2px clear, 2px barely-black.
          → Simulates the fine vertical lines in real wood grain.
          → opacity 0.03 = almost invisible but adds micro-texture.

        Layer 2: repeating-linear-gradient at 180°
          → Horizontal stripes every 5px with a faint amber tint.
          → Adds the horizontal "ring" lines you see when wood is cut.
          → The warm rgba(180,120,40) colour hints at amber sap/resin.

        Layer 3 (bottom): a diagonal linear-gradient
          → Drifts between the olive-dark and green-dark tones.
          → The 160° angle mimics how wood grain runs diagonally
            across a plank — never perfectly horizontal or vertical.
          → Alternating between slightly olive and slightly green hues
            (1a1a0e, 1e1a08, 1a1e0a) gives the forest undertone.

        background-color: #1a1a0e is the ultimate fallback if the
        browser can't render gradients (very rare in 2024).
        ════════════════════════════════════════════════════════════════
    */
    background-color: #1a1a0e;
    background-image:
        repeating-linear-gradient(
            90deg,
            transparent,
            transparent 2px,
            rgba(0, 0, 0, 0.03) 2px,
            rgba(0, 0, 0, 0.03) 4px
        ),
        repeating-linear-gradient(
            180deg,
            transparent,
            transparent 4px,
            rgba(180, 120, 40, 0.03) 4px,
            rgba(180, 120, 40, 0.03) 5px
        ),
        linear-gradient(
            160deg,
            #1a1a0e 0%,
            #1e1a08 20%,
            #1a1e0a 40%,
            #1e1a08 60%,
            #181e08 80%,
            #1a1a0e 100%
        );

    color: var(--cream);                /* Default text colour for the whole page */
    font-family: var(--font-body);
    font-size: 16px;                    /* Base font size — rem values are relative to this */
    line-height: 1.7;                   /* Spacing between lines — 1.7 = comfortable readability */
    overflow-x: hidden;
}

/*
    BODY::BEFORE — SVG NOISE / GRAIN OVERLAY
    ════════════════════════════════════════════════════════════════
    This pseudo-element adds a very subtle film-grain texture over
    the ENTIRE page, layered on top of the CSS wood grain gradients.

    HOW IT WORKS:
    ─────────────────────────────────────────────────────────────
    • position: fixed — the overlay stays fixed to the viewport,
      not the page. It covers the whole screen and doesn't scroll.

    • width: 100%; height: 100% — covers the full viewport.

    • pointer-events: none — you can click/scroll through it.
      It's purely visual, like a transparent sheet of textured glass.

    • z-index: 0 — sits BELOW all content (which uses z-index: 1
      via the nav, section, footer rules above).

    • opacity: 0.4 — the overall transparency of the grain overlay.
      Lower = more subtle. Higher = more visible film grain.

    • background-image uses an inline SVG encoded as a data URL.
      The SVG contains an <feTurbulence> filter — this is a
      mathematical noise function (fractalNoise) that browsers
      render as random speckles. It's the same algorithm used in
      Photoshop's "Add Noise" filter, running live in CSS.

      baseFrequency="0.65" — controls grain size. Higher = finer grain.
      numOctaves="3" — how many detail layers. More = more complex noise.
      stitchTiles="stitch" — tiles the pattern seamlessly.

      The <feColorMatrix type="saturate" values="0"> converts the
      noise to greyscale (removes colour from the random speckles).

      opacity="0.08" on the <rect> is a second opacity reduction
      inside the SVG itself, in addition to the CSS opacity: 0.4.
      Combined effect: 0.4 × 0.08 = 0.032 — extremely subtle.
    ════════════════════════════════════════════════════════════════
*/
body::before {
    content: '';
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;    /* Clicks pass straight through to content below */
    z-index: 0;              /* Below all content (content uses z-index: 1) */
    opacity: 0.4;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='400'%3E%3Cfilter id='grain'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='400' height='400' filter='url(%23grain)' opacity='0.08'/%3E%3C/svg%3E");
}

/* Remove bullet points from all lists */
ul {
    list-style: none;
}

/* Remove underlines from all links (we add our own styling per-link) */
a {
    text-decoration: none;
    color: inherit;                     /* Links inherit the text colour of their parent */
}

/* Responsive images — they scale down but never overflow their container */
img {
    max-width: 100%;
    height: auto;
    display: block;                     /* Removes the mysterious gap below inline images */
}


/* ================================================================
   03. TYPOGRAPHY
   ================================================================
   Default heading styles. All <h1> through <h4> get the
   Merriweather serif font and gold colour.
================================================================ */

h1, h2, h3, h4 {
    font-family: var(--font-heading);
    color: var(--gold);
    line-height: 1.3;                   /* Tighter line-height for headings than body text */
}


/* ================================================================
   04. BUTTONS
   ================================================================
   Shared styles for all .btn elements. We then have modifier
   classes (.btn-primary, .btn-secondary etc.) that change
   specific properties for each button style.

   This is the "BEM-like" approach: base class + modifier.
================================================================ */

.btn {
    display: inline-block;             /* Allows width/padding on an <a> tag */
    padding: 0.75rem 1.5rem;           /* Vertical 12px, horizontal 24px */
    border-radius: var(--radius-md);
    font-family: var(--font-body);
    font-size: 0.95rem;
    font-weight: 600;
    cursor: pointer;
    border: none;
    text-align: center;
    /*
        transition: all 0.2s ease
        When properties change (e.g. on hover), they animate
        smoothly over 0.2 seconds instead of snapping instantly.
    */
    transition: all 0.2s ease;
}

/* Primary button — warm amber-to-gold gradient fill */
.btn-primary {
    background: linear-gradient(135deg, var(--amber), var(--gold));
    color: var(--bg-dark);             /* Dark text on bright button for contrast */
    box-shadow: 0 4px 15px rgba(212, 130, 26, 0.3); /* Warm amber glow under button */
}
.btn-primary:hover {
    transform: translateY(-2px);       /* Lifts the button 2px upward on hover */
    box-shadow: 0 6px 20px rgba(212, 130, 26, 0.5);
}

/* Secondary button — transparent with a simple border */
.btn-secondary {
    background: transparent;
    color: var(--cream);
    border: 1px solid var(--border);
}
.btn-secondary:hover {
    border-color: var(--amber);
    color: var(--amber);
    transform: translateY(-2px);
}

/* Twitch button — Twitch's signature purple */
.btn-twitch {
    background: #9147ff;
    color: white;
    box-shadow: 0 4px 15px rgba(145, 71, 255, 0.3);
}
.btn-twitch:hover {
    background: #a970ff;               /* Lighter purple on hover */
    transform: translateY(-2px);
}

/* Community card button — small, amber outline */
.btn-community {
    background: transparent;
    color: var(--amber);
    border: 1px solid var(--amber);
    font-size: 0.85rem;
    padding: 0.5rem 1rem;
    margin-top: auto;                  /* Pushes button to bottom of its card */
}
.btn-community:hover {
    background: var(--amber);
    color: var(--bg-dark);
    transform: translateY(-2px);
}


/* ================================================================
   05. NAVBAR
   ================================================================
   Fixed/sticky navigation bar that stays at the top of the
   screen as the user scrolls. Uses flexbox to arrange
   the logo on the left and links on the right.
================================================================ */

.navbar {
    /*
        position: fixed — removes the element from the normal
        document flow and pins it relative to the VIEWPORT
        (the browser window), not the page.
        It stays in place as you scroll.
    */
    position: fixed;
    top: 0;
    left: 0;
    right: 0;

    /*
        z-index controls layering. Higher = on top.
        1000 ensures the navbar sits above everything else.
    */
    z-index: 1000;

    /*
        NAVBAR WOOD GRAIN BACKGROUND
        ─────────────────────────────────────────────────────────────
        A two-layer grain: tight vertical stripes over a vertical
        gradient that's slightly lighter at top and bottom edges —
        like light catching the top and bottom rails of a wooden sign.

        We target .navbar specifically rather than the broader
        nav, [class*="nav"] selector — otherwise the wood grain
        background-image would conflict with the wooden button PNG
        backgrounds set on .nav-btn-* elements.

        rgba(22,20,8,0.95): 95% opacity keeps the backdrop-filter
        blur slightly active — content scrolling behind will still
        blur faintly through the navbar.
    */
    background-color: rgba(22, 20, 8, 0.97);
    background-image:
        repeating-linear-gradient(
            90deg,
            transparent,
            transparent 3px,
            rgba(0, 0, 0, 0.05) 3px,
            rgba(0, 0, 0, 0.05) 4px
        ),
        linear-gradient(
            180deg,
            #1a1608 0%,
            #161408 50%,
            #1a1608 100%
        );

    /*
        backdrop-filter: blur() creates a frosted-glass effect
        by blurring whatever is behind the element.
    */
    backdrop-filter: blur(8px);

    border-bottom: 1px solid var(--border);
    padding: 0 var(--space-lg);

    /* Smooth box-shadow transition for the scroll effect in JS */
    transition: box-shadow 0.3s ease;
}

/* Inner wrapper — limits width and centres the navbar content */
.nav-container {
    max-width: 1200px;
    margin: 0 auto;                    /* 0 top/bottom, auto left/right = horizontal centering */
    display: flex;
    justify-content: space-between;    /* Logo left, links right */
    align-items: center;               /* Vertically centre both */
    height: 64px;                      /* Fixed navbar height */
}

/* Logo text on the left */
.nav-logo {
    font-family: var(--font-heading);
    font-size: 1.2rem;
    color: var(--gold);
    font-weight: 700;
    transition: color 0.2s;
}
.nav-logo:hover {
    color: var(--amber);
}

/* The <ul> list of nav links */
.nav-links {
    display: flex;
    /*
        Reduced gap compared to before — the wooden button images are
        wider than plain text links, so we use a tighter gap to fit
        all 6 buttons comfortably in the navbar.
    */
    gap: 8px;
    align-items: center;
}

/*
    NAV LINK — BASE STYLES
    ──────────────────────
    The wooden button images (About_Me.png, Schedule.png, etc.)
    are used as the BACKGROUND of each <a> link element.

    To achieve this:
    - We set explicit width and height matching the button proportions
    - We set background-image, background-size, background-repeat
    - We hide the text (it's already in the image) using color: transparent
    - We keep the text in the HTML for accessibility (screen readers can still read it)
    - On hover, filter: brightness(1.2) makes the button glow brighter

    The wooden buttons are approximately 430×100px — a 4.3:1 width-to-height ratio.
    We display them at 148px × 38px to fit all 6 in the navbar.
*/
.nav-link {
    display: inline-block;
    width: 148px;                       /* Fixed width to match button image proportions */
    height: 38px;                       /* Fixed height — scales down from natural size */

    background-repeat: no-repeat;
    background-position: center;
    /*
        background-size: 100% 100% stretches the image to fill the element exactly.
        This keeps the wooden frame filling the full button area with no gaps.
    */
    background-size: 100% 100%;

    /*
        Make the link text invisible — the button image already has the text
        baked in as part of the artwork. We keep the HTML text so screen
        readers (used by visually impaired users) can still read "About Me",
        "Schedule" etc. aloud.

        color: transparent hides the text without removing it.
        font-size: 0 prevents the invisible text from creating unexpected height.
    */
    color: transparent;
    font-size: 0;

    /*
        filter: brightness() lightens or darkens an element.
        1.0 = normal. 1.2 = 20% brighter. Used on hover for a glow effect.
    */
    transition: filter 0.2s ease, transform 0.15s ease;
}
.nav-link:hover {
    color: transparent;                  /* Keep text invisible on hover too */
    filter: brightness(1.2);            /* Brighten the wooden button image on hover */
    transform: translateY(-1px);        /* Slight lift for a tactile feel */
}

/*
    Remove the sliding underline animation — it was designed for text links.
    With image buttons, we don't want any underline effect.
    Setting content to nothing (or removing) disables the pseudo-element.
*/
.nav-link::after {
    display: none;
}

/*
    ═══════════════════════════════════════════════════════
    INDIVIDUAL WOODEN BUTTON IMAGES
    ═══════════════════════════════════════════════════════
    Each nav button gets its own background image.
    The image filenames match the assets in the project folder.

    Button image assets used here:
    - About_Me.png  → wooden button with "About Me" text
    - Schedule.png  → wooden button with "Schedule" text
    - Links.png     → wooden button with "Links" text (used for Stream)
    - Games.png     → wooden button with "Games" text (used for NutDex)
    - Discord.png   → wooden button with "Discord" text (used for Community)
    - My_Specs.png  → wooden button with "My Specs" text (used for Setup)
    ═══════════════════════════════════════════════════════
*/

/* About Me button — links to #about section */
.nav-btn-about {
    background-image: url('About_Me.png');
}

/* Schedule button — links to #schedule section */
.nav-btn-schedule {
    background-image: url('Schedule.png');
}

/*
    Stream button — uses Links.png (no dedicated "Stream" button image).
    Links.png fits well here as it implies external/stream links.
*/
.nav-btn-stream {
    background-image: url('Links.png');
}

/*
    NutDex button — uses Games.png (NutDex is the card collection game section).
    Games.png is the closest matching asset.
*/
.nav-btn-nutdex {
    background-image: url('Games.png');
}

/* Discord/Community button — links to #community section */
.nav-btn-community {
    background-image: url('Discord.png');
}

/* My Specs/Setup button — links to #setup section */
.nav-btn-setup {
    background-image: url('My_Specs.png');
}

/*
    Note: .section-banner-img styles removed.
    The wooden button images now appear ONLY in the navbar (nav-btn-*).
    Section headings use the wooden sign CSS styling on .section-title instead.
*/

/*
    HAMBURGER BUTTON
    Hidden on desktop (display: none).
    Shown on mobile via the @media query at the bottom of this file.
*/
.hamburger {
    display: none;
    background: none;
    border: 1px solid var(--border);
    color: var(--cream);
    font-size: 1.4rem;
    padding: var(--space-xs) var(--space-sm);
    cursor: pointer;
    border-radius: var(--radius-sm);
    line-height: 1;
    transition: border-color 0.2s, color 0.2s;
}
.hamburger:hover {
    border-color: var(--amber);
    color: var(--amber);
}


/* ================================================================
   06. HERO SECTION
   ================================================================
   Full-viewport-height welcome section. Features:
   - CSS forest background (no images needed)
   - Glowing circular avatar
   - Fade-up entrance animation
================================================================ */

.hero {
    /*
        min-height: 100vh = at least 100% of the viewport height.
        The section will be at least as tall as the browser window.
    */
    min-height: 100vh;

    display: flex;
    align-items: center;               /* Vertically centres content */
    justify-content: center;           /* Horizontally centres content */
    text-align: center;

    position: relative;                /* Needed so .hero-bg can be positioned inside it */
    padding-top: 64px;                 /* Offset for the 64px-tall fixed navbar */
    padding-left: var(--space-lg);
    padding-right: var(--space-lg);
    /*
        overflow: hidden removed — it would clip background-attachment: fixed
        in some browsers, preventing the parallax effect from rendering.
    */
}

/*
    PARALLAX HERO BACKGROUND
    ════════════════════════════════════════════════════════════════════
    The banner image now lives on #home itself (the section element),
    not on the .hero-bg child div. This enables background-attachment: fixed.

    HOW PARALLAX WORKS:
    ────────────────────────────────────────────────────────────────────
    background-attachment: fixed pins the background image to the VIEWPORT
    rather than to the element. As the user scrolls down, the page content
    moves but the background stays still — the image appears to scroll at a
    different speed, creating an illusion of depth.

    Think of it like looking out of a moving car: the trees close to the
    road blur past, but distant mountains barely move. The content is the
    trees; the fixed background is the mountains.

    HOW THE ZOOM ANIMATION WORKS:
    ────────────────────────────────────────────────────────────────────
    @keyframes heroZoom animates background-size from 110% (slightly
    larger than needed) down to cover (exactly filling the viewport).
    The effect is a subtle "settle into place" on page load — the image
    gently zooms to its final framing over 2 seconds.

    animation-fill-mode: forwards keeps the final state (cover) after
    the animation completes, so there's no jump back to 110%.

    NOTE: background-attachment: fixed is ignored on iOS Safari (a known
    browser bug). On mobile the image simply scrolls normally — which is
    fine since mobile layouts use a simpler single-column design anyway.
    ════════════════════════════════════════════════════════════════════
*/
#home {
    background-image: url('Banner_Twitch.png');
    background-attachment: fixed;    /* Pin to viewport — the parallax key */
    background-position: center;
    background-size: cover;
    background-repeat: no-repeat;
    animation: heroZoom 2s ease forwards;
}

@keyframes heroZoom {
    from { background-size: 110%; }  /* Starts slightly oversized */
    to   { background-size: cover; } /* Settles to full coverage */
}

/*
    .hero-bg is now a PURE GRADIENT OVERLAY — no background image.
    It sits between the parallax image (on #home) and the hero content.

    Layer order (bottom to top):
    1. #home background: Banner_Twitch.png (parallax, fixed)
    2. .hero-bg: dark gradient overlay (dims the image for text legibility)
    3. .hero-content: avatar, title, buttons (z-index: 1)
*/
.hero-bg {
    position: absolute;
    inset: 0;
    background-image: linear-gradient(
        to bottom,
        rgba(8, 8, 4, 0.55) 0%,        /* Slightly dark at top (navbar area) */
        rgba(8, 8, 4, 0.45) 50%,       /* Lightest in the middle — art shows through */
        rgba(26, 26, 14, 0.75) 100%    /* Fades into --bg-dark at the bottom */
    );
}

/* The actual content — needs to be above the background layer */
.hero-content {
    position: relative;
    z-index: 1;                        /* z-index > 0 puts this above .hero-bg */
    display: flex;
    flex-direction: column;            /* Stack children vertically */
    align-items: center;
    gap: var(--space-lg);
    max-width: 700px;
    /*
        Animation: slides up and fades in when page loads.
        Defined in the @keyframes block further down.
    */
    animation: heroEntrance 0.8s ease-out both;
}

@keyframes heroEntrance {
    from {
        opacity: 0;
        transform: translateY(20px);   /* Starts 20px lower */
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/*
    PROFILE IMAGE WRAPPER
    Creates the glowing amber ring around the image.
    The gradient + box-shadow produce the candlelight glow.
*/
.hero-avatar-wrapper {
    padding: 4px;                      /* The "ring" width (gap between gradient and image) */
    border-radius: 50%;                /* Makes the wrapper circular */
    background: linear-gradient(135deg, var(--amber), var(--gold));
    box-shadow:
        0 0 25px rgba(212, 130, 26, 0.5),   /* Inner glow (close, strong) */
        0 0 70px rgba(212, 130, 26, 0.2);   /* Outer glow (far, soft) */
    animation: avatarPulse 3s ease-in-out infinite alternate;
}

/* Gentle pulse on the glow — makes it feel alive */
@keyframes avatarPulse {
    from {
        box-shadow: 0 0 25px rgba(212, 130, 26, 0.5), 0 0 70px rgba(212, 130, 26, 0.2);
    }
    to {
        box-shadow: 0 0 35px rgba(212, 130, 26, 0.8), 0 0 90px rgba(212, 130, 26, 0.4);
    }
}

/* The profile image — circular crop */
.hero-avatar {
    width: 180px;
    height: 180px;
    border-radius: 50%;
    object-fit: cover;                 /* Crops image to fill the circle (no stretching) */
    border: 3px solid var(--bg-dark); /* Dark gap between image edge and the glow ring */
    display: block;
}

/* Main h1 title */
.hero-title {
    /*
        clamp(min, preferred, max) = responsive font size.
        - Never smaller than 2.5rem
        - Tries to be 6% of the viewport width
        - Never larger than 4rem
        This makes the heading scale nicely on all screen sizes.
    */
    font-size: clamp(2.5rem, 6vw, 4rem);
    color: var(--gold);
    text-shadow: 0 0 40px rgba(240, 165, 0, 0.4); /* Glow effect around text */
    letter-spacing: 0.02em;
}

/* Tagline / subtitle paragraph */
.hero-subtitle {
    font-size: clamp(1rem, 2.5vw, 1.2rem);
    color: var(--cream);
    max-width: 520px;
    opacity: 0.9;
}

/* Row of CTA buttons */
.hero-buttons {
    display: flex;
    gap: var(--space-md);
    flex-wrap: wrap;                   /* Wraps to second row on small screens */
    justify-content: center;
}

/* Row of milestone badges */
.hero-milestones {
    display: flex;
    gap: var(--space-sm);
    flex-wrap: wrap;
    justify-content: center;
}

/* Individual milestone badge pill */
.milestone-badge {
    background-color: rgba(240, 165, 0, 0.1);     /* Very subtle gold tint */
    border: 1px solid rgba(240, 165, 0, 0.3);
    color: var(--gold);
    font-size: 0.75rem;
    padding: var(--space-xs) var(--space-sm);
    border-radius: 100px;              /* 100px makes it a pill shape */
    font-weight: 500;
    white-space: nowrap;               /* Prevents each badge wrapping mid-text */
}


/* ================================================================
   07. SHARED SECTION STYLES
   ================================================================
   Reused across every content section for consistent spacing.
================================================================ */

/* Every section has the same vertical padding */
.section {
    padding: var(--space-xl) var(--space-lg);
}

/*
    ALTERNATE SECTION — SLIGHTLY LIGHTER WOOD GRAIN
    ─────────────────────────────────────────────────────────────────
    Same three-layer technique as body, but with:
    - A 88° grain angle (almost horizontal) — different plank orientation
    - rgba(160,100,20) for the amber ring lines — slightly richer tone
    - The diagonal base gradient uses #1e1e12/#221e0c/#1e2210 —
      a touch lighter and greener, creating visual rhythm between sections
*/
.section-alt {
    background-color: #1e1e12;
    background-image:
        repeating-linear-gradient(
            88deg,
            transparent,
            transparent 3px,
            rgba(0, 0, 0, 0.02) 3px,
            rgba(0, 0, 0, 0.02) 6px
        ),
        repeating-linear-gradient(
            180deg,
            transparent,
            transparent 3px,
            rgba(160, 100, 20, 0.04) 3px,
            rgba(160, 100, 20, 0.04) 4px
        ),
        linear-gradient(
            150deg,
            #1e1e12 0%,
            #221e0c 25%,
            #1e2210 50%,
            #221e0c 75%,
            #1e1e12 100%
        );
}

/*
    CARD BACKGROUNDS — DARKER WOOD GRAIN
    ─────────────────────────────────────────────────────────────────
    Cards (character card, community cards, setup card, etc.) sit
    slightly above the section surface — like wooden objects resting
    on a wooden floor. They use a 92° grain (nearly horizontal) at a
    slightly darker base (#241a08) so they contrast against sections.

    [class*="card"] targets any element whose class CONTAINS the word
    "card" — so .character-card, .schedule-card, .tcg-card, etc.
    More specific rules like .schedule-card.schedule-live will still
    override this where their own styling is needed (CSS specificity).
*/
.card,
[class*="card"] {
    background-color: #241a08;
    background-image:
        repeating-linear-gradient(
            92deg,
            transparent,
            transparent 2px,
            rgba(0, 0, 0, 0.04) 2px,
            rgba(0, 0, 0, 0.04) 3px
        ),
        linear-gradient(
            170deg,
            #241a08 0%,
            #2a1e0a 30%,
            #241e0c 60%,
            #241a08 100%
        );
}

/*
    STACKING CONTEXT — CONTENT ABOVE GRAIN OVERLAY
    ─────────────────────────────────────────────────────────────────
    The body::before grain overlay (defined below) uses
    position: fixed; z-index: 0.
    Setting position: relative; z-index: 1 on these top-level elements
    ensures all page content sits above the overlay.
    Without this, the grain could render on top of the content.
*/
nav,
section,
footer {
    position: relative;
    z-index: 1;
}


/* ================================================================
   SMOOTH SECTION TRANSITIONS
   ================================================================
   Instead of hard colour edges where sections meet, each section
   fades out at its top and bottom using gradient pseudo-elements.

   HOW THIS WORKS:
   ───────────────────────────────────────────────────────────────
   • section::before — a gradient from --bg-dark → transparent,
     placed at the TOP of the section. It makes the section's
     background appear to dissolve into the colour above it.

   • section::after — the mirror image at the BOTTOM, fading the
     section background out into --bg-dark below.

   • Both gradients use pointer-events: none so they don't block
     mouse clicks, hover effects, or touch interactions.

   • z-index: 2 — the fades sit ABOVE the section's background
     (z-index: 0) but BELOW the section's content (z-index: 3).

   WHY :not(.hero):
   ───────────────────────────────────────────────────────────────
   The hero section (.hero) is excluded because:
   1. It fills the full viewport — a top fade would dim the banner.
   2. The hero content uses z-index: 1, which would end up UNDER
      the fade overlay (z-index: 2) and become partially hidden.
   All other sections are safe since their content goes through
   the section > * rule below (z-index: 3).
================================================================ */
section:not(.hero)::before {
    content: '';
    position: absolute;   /* Positioned inside the section's box */
    top: 0;
    left: 0;
    right: 0;
    height: 80px;
    /*
        Gradient: --bg-dark (opaque) at the very top edge of the
        section, fading to transparent further down.
        The section's own background shows through the transparent part.
        Net effect: the section appears to emerge from the dark page.
    */
    background: linear-gradient(to bottom, var(--bg-dark), transparent);
    pointer-events: none;
    z-index: 2;
}

section:not(.hero)::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 80px;
    /*
        Mirror of ::before — --bg-dark at the very bottom edge,
        fading to transparent upward. The section melts into the
        dark page below rather than having a sharp cut.
    */
    background: linear-gradient(to top, var(--bg-dark), transparent);
    pointer-events: none;
    z-index: 2;
}

/*
    Make section content sit ABOVE the fade overlays.
    Without this, the gradients (z-index: 2) would render on top
    of the section's text and cards.

    section > * targets DIRECT children of sections — in our HTML
    that's the .container div inside each <section>.
    The .container then wraps all the visible content.

    We exclude .hero because it manages its own z-index separately
    (.hero-bg at z-index 0, .hero-content at z-index 1).
*/
section:not(.hero) > * {
    position: relative;
    z-index: 3;
}

/* Inner container — limits max width and centres the content */
.container {
    max-width: 1100px;
    margin: 0 auto;
}

/*
    SECTION TITLE — WOODEN TAVERN SIGN STYLE
    ─────────────────────────────────────────
    Each section heading is styled to look like text carved into or
    painted onto a wooden tavern sign / plank.

    HOW THE EFFECT WORKS:
    ┌────────────────────────────────────────────────────────────┐
    │  display: block + width: fit-content + margin: 0 auto      │
    │  → Shrinks to hug the text tightly, then centres itself.   │
    │    (Like inline-block but centrable without changing the    │
    │    parent element's text-align.)                           │
    │                                                            │
    │  background: linear-gradient(135deg, ...)                  │
    │  → Three-stop diagonal gradient simulates the light and    │
    │    shadow across a curved wooden surface: dark edge →      │
    │    lighter mid-plank highlight → dark edge again.          │
    │                                                            │
    │  text-shadow: 2px 2px 4px #000, 0 0 8px rgba(...)         │
    │  → First shadow: hard dark offset drop shadow — makes text │
    │    look pressed/carved into the wood (depth).              │
    │  → Second shadow: diffuse warm amber glow — candlelight    │
    │    reflecting off the carved lettering.                    │
    │                                                            │
    │  box-shadow: outer + inset                                 │
    │  → Outer: drop shadow under the plank (lifts it off page). │
    │  → Inset top highlight: bright sliver at top edge —        │
    │    simulates light catching the top edge of the wood.      │
    └────────────────────────────────────────────────────────────┘
*/
.section-title {
    /* Keep Merriweather but bold — carved text needs weight */
    font-family: var(--font-heading);
    font-size: clamp(1.6rem, 3.5vw, 2.2rem);
    font-weight: 700;

    /* Warm cream — like aged ivory paint or pale carved wood */
    color: #f5e6c8;

    /*
        Two-layer text shadow:
        1. Hard dark offset: gives the carved/engraved depth illusion
        2. Soft amber glow: warm candlelight bouncing off the letters
    */
    text-shadow:
        2px 2px 4px #000,
        0 0 8px rgba(180, 100, 20, 0.4);

    /*
        Wooden plank gradient:
        - Dark edge (#5c3510) → light centre (#8b5e2a) → dark edge (#5c3510)
        - 135deg diagonal mimics natural wood grain catching light
    */
    background: linear-gradient(135deg, #5c3510, #8b5e2a, #5c3510);

    /* Breathing room around the text — makes the plank feel solid */
    padding: 12px 40px;

    /* Slight rounding — real planks have worn edges, not sharp corners */
    border-radius: 8px;

    /* Amber-brown border — like a carved or painted frame on the sign */
    border: 2px solid #c4832a;

    /*
        Two-layer box shadow:
        - Outer: lifts the sign off the page with a dark cast shadow
        - Inset top edge: bright highlight simulating light on the top rim
    */
    box-shadow:
        0 4px 12px rgba(0, 0, 0, 0.5),
        inset 0 1px 0 rgba(255, 200, 100, 0.2);

    /*
        display: block + width: fit-content = the element fills only
        as much width as its text needs (like inline-block), but
        margin: 0 auto then centres that shrunk block element.
        This is cleaner than inline-block because it doesn't require
        the parent to have text-align: center.
    */
    display: block;
    width: fit-content;
    margin: 0 auto var(--space-md);

    text-align: center;
}

/*
    Remove the old gold underline — the wooden sign style replaces it.
    display: none hides the pseudo-element entirely.
*/
.section-title::after {
    display: none;
}

/* Subtitle paragraph under the section heading */
.section-subtitle {
    text-align: center;
    color: var(--muted);
    font-size: 1rem;
    margin-bottom: var(--space-xl);
}


/* ================================================================
   08. ABOUT — CHARACTER CARD
   ================================================================
   Styled as a cosy fantasy RPG character sheet / inn register.
   Features corner ornaments, dot dividers, and a warm inner glow.
================================================================ */

.character-card {
    background-color: var(--bg-card);
    border: 1px solid var(--border);

    /*
        Multiple box-shadows:
        - inset: glow INSIDE the card (candlelight warmth)
        - regular: soft shadow beneath the card
    */
    box-shadow:
        inset 0 0 80px rgba(212, 130, 26, 0.03),
        0 8px 40px rgba(0, 0, 0, 0.5);

    border-radius: var(--radius-lg);
    padding: 3rem;
    max-width: 700px;
    margin: 0 auto;

    /*
        position: relative allows the corner ornaments to be
        positioned absolutely RELATIVE TO this card.
    */
    position: relative;

    /* Subtle parchment-like radial gradient from the top */
    background-image: radial-gradient(ellipse at top, rgba(212, 130, 26, 0.06) 0%, transparent 60%);
}

/* Card header row — label on left, stamp on right */
.character-card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    border-bottom: 1px solid var(--border);
    padding-bottom: var(--space-md);
    margin-bottom: var(--space-lg);
}

/* "Adventurer's Profile" label */
.card-label {
    font-family: var(--font-heading);
    font-size: 0.85rem;
    color: var(--amber);
    letter-spacing: 0.1em;
}

/* "Verified ✓" stamp */
.card-stamp {
    font-size: 0.75rem;
    color: var(--green-mid);
    border: 1px solid var(--green-mid);
    padding: 2px 8px;
    border-radius: 3px;
    font-weight: 600;
}

/* Container for all stat rows */
.character-stats {
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
}

/*
    One stat row: Label ·········· Value
    display: flex with align-items: baseline aligns the text
    along the bottom of each element (looks tidiest with mixed sizes).
*/
.stat-row {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
    flex-wrap: wrap;
}

/* Label on the left (Name, Age, etc.) */
.stat-label {
    color: var(--amber);
    font-family: var(--font-heading);
    font-size: 0.85rem;
    font-weight: 700;
    min-width: 115px;                  /* Fixed minimum width so all labels align */
    flex-shrink: 0;                    /* Prevents this from shrinking */
}

/* The dotted line that fills the space between label and value */
.stat-dots {
    flex: 1;                           /* Takes all remaining horizontal space */
    color: var(--border);
    letter-spacing: -0.05em;          /* Tighten the dots slightly */
    overflow: hidden;                  /* Don't let dots overflow */
    white-space: nowrap;
}

/* Value on the right */
.stat-value {
    color: var(--cream);
    font-size: 0.95rem;
    flex-shrink: 0;
}

/* Small greyed-out note in parentheses */
.stat-note {
    font-size: 0.8rem;
    color: var(--muted);
    font-style: italic;
}

/* Thin horizontal line separating stat groups */
.stat-divider-line {
    height: 1px;
    background-color: var(--border);
    margin: var(--space-xs) 0;
}

/*
    CORNER ORNAMENTS
    position: absolute places these relative to the card (.character-card).
    Each corner class positions the ❧ in a different corner.
    transform: scale(-1) mirrors it for the opposing corners.
*/
.card-corner {
    position: absolute;
    color: var(--amber);
    font-size: 1.1rem;
    opacity: 0.35;
    line-height: 1;
}
.top-left     { top: 14px;    left: 14px;  }
.top-right    { top: 14px;    right: 14px; transform: scaleX(-1); }
.bottom-left  { bottom: 14px; left: 14px;  transform: scaleY(-1); }
.bottom-right { bottom: 14px; right: 14px; transform: scale(-1);  }


/* ================================================================
   08b. ACHIEVEMENT TIMELINE (About Section)
   ================================================================
   A winding path timeline showing Meg's key streaming milestones.
   It's built from two parts that work together:

   PART A — the SVG (Scalable Vector Graphics) winding path
   PART B — HTML divs (.timeline-node) positioned over the SVG

   HOW SVG PATHS WORK:
   ───────────────────────────────────────────────────────────────
   SVG uses a "path" element with a series of drawing commands in
   the "d" attribute. Think of it like telling a pen where to move:

     M 250 30       = Move to coordinate (250, 30) — no line drawn
     C 200 60,      = Cubic Bezier curve — uses TWO control points
       80 80,         to define the "pull" direction of the curve.
       60 130         This endpoint is where the curve ends.

   A Cubic Bezier curve (C command) needs 3 pairs of coordinates:
     C cx1 cy1, cx2 cy2, x y
     - (cx1, cy1): first control point (pulls the curve from the start)
     - (cx2, cy2): second control point (pulls the curve at the end)
     - (x, y): the endpoint the curve reaches

   The viewBox="0 0 300 400" means the SVG coordinate system is
   300 units wide and 400 units tall — matching the container px size
   so 1 SVG unit = 1 CSS pixel here.

   HOW THE DRAWING ANIMATION WORKS:
   ───────────────────────────────────────────────────────────────
   stroke-dasharray sets the length of dashes and gaps.
   Setting stroke-dasharray to the FULL path length (≈600) and
   stroke-dashoffset to the same value makes the path invisible
   (the gap starts at position 0, hiding the entire line).

   Animating stroke-dashoffset from 600 → 0 slides the gap
   backwards, revealing the path from start to end — like drawing
   a line with a pen. This is a classic SVG animation trick.

   POSITIONING NODES OVER THE SVG:
   ───────────────────────────────────────────────────────────────
   .timeline-container uses position: relative.
   .timeline-path (the SVG) is position: absolute, filling the box.
   .timeline-node elements are also position: absolute.

   The top/left values on each node are tuned by eye to sit near
   the corresponding point on the SVG path curve. The SVG coordinate
   (x, y) maps roughly to (x px, y px) in the container.
================================================================ */

/* Outer container — defines the coordinate space for the SVG and nodes */
.timeline-container {
    position: relative;
    width: 300px;
    height: 400px;
    margin: 40px auto;   /* Centres the whole timeline block */
}

/* The SVG fills the container absolutely, behind the nodes */
.timeline-path {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

/*
    Each node is absolutely positioned to sit at a point on the path.
    display: flex puts the dot and card side by side on one line.
    align-items: center vertically centres them relative to each other.
*/
.timeline-node {
    position: absolute;
    display: flex;
    align-items: center;
    gap: 10px;
}

/*
    The circular dot — styled as a glowing amber star button.
    flex-shrink: 0 prevents it from squishing when space is tight.
    z-index: 2 keeps it above the SVG path stroke visually.
*/
.node-dot {
    width: 36px;
    height: 36px;
    background: linear-gradient(135deg, var(--amber), var(--gold));
    border-radius: 50%;
    border: 2px solid var(--gold);
    box-shadow: 0 0 12px rgba(240, 165, 0, 0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
    flex-shrink: 0;
    z-index: 2;
}

/* Achievement card — mini card next to each dot */
.node-card {
    background: #241a08;
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 8px 12px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
    min-width: 140px;
}

/* Date label in amber — stands out as metadata */
.node-date {
    font-size: 11px;
    color: var(--amber);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

/* Milestone name in bold cream */
.node-title {
    font-size: 14px;
    color: var(--cream);
    font-weight: 700;
    margin: 2px 0;
}

/* Short description in muted italic */
.node-desc {
    font-size: 12px;
    color: var(--muted);
    font-style: italic;
}

/*
    PATH DRAW ANIMATION
    ───────────────────────────────────────────────────────────────
    #wind-path targets the dashed foreground path by its id.
    stroke-dasharray: 600 — one giant "dash" as long as the whole path
    stroke-dashoffset: 600 — shifts that dash 600 units forward,
      making the path invisible (showing only the "gap" instead)
    animation: drawPath — animates offset to 0, revealing the path
    animation-delay: 0.5s — short pause before drawing starts
*/
#wind-path {
    stroke-dasharray: 600;
    stroke-dashoffset: 600;
    animation: drawPath 2s ease forwards;
    animation-delay: 0.5s;
}

@keyframes drawPath {
    to {
        stroke-dashoffset: 0;   /* Path fully visible — gap has slid past the end */
    }
}

/*
    NODE FADE-IN ANIMATIONS
    ───────────────────────────────────────────────────────────────
    Nodes start invisible (opacity: 0) and fade in sequentially
    as the path finishes drawing past their position.

    :nth-child(n) counts the children of .timeline-container:
      child 1 = the <svg> element (the path — no animation)
      child 2 = first .timeline-node (First Stream)
      child 3 = second .timeline-node (Twitch Affiliate)
      child 4 = third .timeline-node (Twitch Partner)

    The staggered delays (1s, 1.5s, 2s) are timed to match
    roughly when the drawing path reaches each node position.
*/
.timeline-node:nth-child(2) {
    opacity: 0;
    animation: fadeInNode 0.5s ease forwards;
    animation-delay: 1s;
}
.timeline-node:nth-child(3) {
    opacity: 0;
    animation: fadeInNode 0.5s ease forwards;
    animation-delay: 1.5s;
}
.timeline-node:nth-child(4) {
    opacity: 0;
    animation: fadeInNode 0.5s ease forwards;
    animation-delay: 2s;
}

@keyframes fadeInNode {
    to { opacity: 1; }
}


/* ================================================================
   09. SCHEDULE
   ================================================================
   Seven day cards in a grid. Live days have warm amber glow.
   Off days are muted.
================================================================ */

.schedule-grid {
    display: grid;
    /*
        repeat(7, 1fr) = 7 equal-width columns.
        "fr" = fraction of available space.
        Each column gets 1/7 of the total width.
    */
    grid-template-columns: repeat(7, 1fr);
    gap: var(--space-md);
    margin-bottom: var(--space-lg);
}

/* Base style shared by all day cards */
.schedule-card {
    border-radius: var(--radius-md);
    padding: 1.25rem var(--space-sm);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.4rem;
    text-align: center;
    transition: transform 0.2s;
}

.schedule-card:hover {
    transform: translateY(-4px);       /* Lift on hover for interactive feel */
}

/* OFF-STREAM DAY — muted, dark, slightly transparent */
.schedule-off {
    background-color: var(--bg-card);
    border: 1px solid var(--border);
    opacity: 0.55;
}

/* LIVE DAY — warm amber glow with candlelight effect */
.schedule-live {
    background-color: var(--bg-card);
    border: 1px solid var(--amber);

    /*
        Multiple shadows:
        - Outer glow (amber, soft)
        - Inner glow (amber, very faint)
    */
    box-shadow:
        0 0 18px rgba(212, 130, 26, 0.18),
        inset 0 0 25px rgba(212, 130, 26, 0.06);

    /* Subtle gradient from top — like candlelight lighting the card */
    background-image: radial-gradient(ellipse at top, rgba(212, 130, 26, 0.1) 0%, transparent 70%);
}

/* Pulsing red ● dot on live days */
.live-dot {
    color: #ff4444;
    font-size: 0.65rem;
    animation: livePulse 1.5s ease-in-out infinite;
}

/* Day name (Monday, Tuesday, etc.) */
.day-name {
    font-family: var(--font-heading);
    font-size: 0.8rem;
    color: var(--cream);
    font-weight: 700;
}

/* "Live" or "No Stream" status label */
.day-status {
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}
.live-status { color: var(--amber); }
.off-status  { color: var(--muted); }

/* Time of stream */
.day-time {
    font-size: 0.75rem;
    color: var(--muted);
}

/* Timezone note below the schedule grid */
.schedule-note {
    text-align: center;
    color: var(--muted);
    font-size: 0.85rem;
    font-style: italic;
}


/* ================================================================
   10. STREAM SECTION
   ================================================================
   Twitch player + chat side by side (flex row).
   Player is wider (flex: 3), chat is narrower (flex: 1).
================================================================ */

/*
    STREAM HEADER
    ─────────────────────────────────────────────────────────────
    The badge and title were previously in a flex row side by side,
    which pushed the title off-centre. Fixed by switching to a
    simple text-align: center block — the badge sits on its own
    line, then the title centres beneath it on its own line.
*/
.stream-header {
    text-align: center;
    margin-bottom: var(--space-sm);
}

/*
    Live badge: display as inline-block so text-align: center on
    the parent centres it. margin-bottom pushes the title down
    so there's breathing room between badge and sign.
*/
.stream-header .live-badge {
    display: inline-block;
    margin-bottom: var(--space-sm);
}

/*
    The .section-title wooden sign already uses:
    display: block; width: fit-content; margin: 0 auto var(--space-md);
    That naturally centres it here — no overrides needed.
    We only suppress the ::after underline (already done globally).
*/
.stream-header .section-title::after {
    display: none;
}

/* Pulsing red "● LIVE" pill badge */
.live-badge {
    background-color: #e03333;
    color: white;
    font-size: 0.78rem;
    font-weight: 700;
    padding: 5px 12px;
    border-radius: 100px;
    letter-spacing: 0.1em;
    animation: livePulse 2s ease-in-out infinite;
    white-space: nowrap;
}

/* Shared pulse animation for all live indicators */
@keyframes livePulse {
    0%, 100% { opacity: 1; }
    50%       { opacity: 0.45; }
}

/* "Open on Twitch" button row */
.stream-open-link {
    text-align: center;
    margin-bottom: var(--space-lg);
}

/*
    PLAYER + CHAT CONTAINER
    display: flex puts the player and chat side by side.
    height: 520px gives both a fixed height.
*/
.stream-container {
    display: flex;
    gap: var(--space-md);
    height: 520px;
}

/* Player takes up 3/4 of the available width */
.stream-player {
    flex: 3;
    border-radius: var(--radius-md);
    overflow: hidden;
    border: 1px solid var(--border);
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
}

/* Chat takes up 1/4 of the available width */
.stream-chat {
    flex: 1;
    border-radius: var(--radius-md);
    overflow: hidden;
    border: 1px solid var(--border);
    min-width: 220px;
}

/* Both iframes fill their containers completely */
.stream-player iframe,
.stream-chat iframe {
    width: 100%;
    height: 100%;
    border: none;
}


/* ================================================================
   11. NUTDEX — TCG PLACEHOLDER CARD
   ================================================================
   Styled to resemble a fantasy trading card game card.
   This is a placeholder — the real NutDex is coming soon.
================================================================ */

/* Centres the card horizontally */
.nutdex-container {
    display: flex;
    justify-content: center;
    margin: var(--space-lg) 0;
}

/* The card itself — portrait orientation, fixed width */
.tcg-card {
    width: 240px;
    background-color: var(--bg-card);
    border-radius: var(--radius-lg);
    overflow: hidden;                  /* Clips the card art at rounded corners */
    border: 2px solid var(--gold);

    /* Layered gold glow around the card */
    box-shadow:
        0 0 20px rgba(240, 165, 0, 0.25),
        0 0 60px rgba(240, 165, 0, 0.1),
        inset 0 0 20px rgba(240, 165, 0, 0.04);

    display: flex;
    flex-direction: column;

    /* Gentle rotation — like it's resting at a slight angle */
    transform: rotate(-1deg);
    transition: transform 0.3s ease;
}
.tcg-card:hover {
    transform: rotate(0deg) scale(1.04); /* Straightens and slightly enlarges on hover */
}

/* Card header — gradient rarity banner */
.tcg-card-top {
    background: linear-gradient(135deg, var(--amber), var(--gold));
    padding: 0.5rem;
    text-align: center;
}
.tcg-rarity {
    font-size: 0.7rem;
    color: var(--bg-dark);
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

/* Card art area — gradient background with large acorn emoji */
.tcg-art {
    /* --green-deep is now dark warm brown (#2a1f0a); bottom rgba matches --bg-card (#241a0a) */
    background: linear-gradient(180deg, var(--green-deep) 0%, rgba(36, 26, 10, 0.5) 100%);
    height: 145px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.tcg-art-icon {
    font-size: 4.5rem;
    filter: drop-shadow(0 4px 8px rgba(0,0,0,0.5));
}

/* Card name banner */
.tcg-name {
    font-family: var(--font-heading);
    font-size: 1rem;
    color: var(--gold);
    text-align: center;
    padding: 0.5rem;
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    background-color: rgba(240, 165, 0, 0.05);
}

/* Card body text */
.tcg-body {
    padding: 0.75rem;
    text-align: center;
    flex: 1;
}
.tcg-coming-soon-text {
    font-size: 0.85rem;
    color: var(--amber);
    font-weight: 600;
    margin-bottom: 0.5rem;
    letter-spacing: 0.05em;
}
.tcg-flavour {
    font-size: 0.72rem;
    color: var(--muted);
    font-style: italic;
    line-height: 1.6;
}

/* Card footer — set name and card number */
.tcg-footer {
    display: flex;
    justify-content: space-between;
    padding: 0.4rem 0.75rem;
    border-top: 1px solid var(--border);
}
.tcg-set, .tcg-number {
    font-size: 0.65rem;
    color: var(--muted);
}

/* "Coming soon" note below the card */
.nutdex-note {
    text-align: center;
    color: var(--muted);
    font-style: italic;
    font-size: 0.9rem;
}


/* ================================================================
   12. COMMUNITY SECTION
   ================================================================
   Grid of cards + subscription info + contact footer.
================================================================ */

/*
    CSS Grid with auto-fill:
    - auto-fill: creates as many columns as will fit
    - minmax(250px, 1fr): each column is at least 250px, max 1fr
    This is fully responsive with NO media queries needed!
    At 1100px wide: fits ~4 columns
    At 800px wide:  fits ~3 columns
    At 500px wide:  fits ~2 columns
*/
.community-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: var(--space-lg);
    margin-bottom: var(--space-xl);
}

/* Individual community card */
.community-card {
    background-color: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: var(--space-lg);
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--space-md);
    transition: all 0.25s ease;
}
.community-card:hover {
    border-color: var(--amber);
    box-shadow: 0 4px 24px rgba(212, 130, 26, 0.12);
    transform: translateY(-4px);
}

/* Large icon at top of card */
.community-card-icon {
    font-size: 2.5rem;
    line-height: 1;
}

/* Card title */
.community-card-title {
    font-family: var(--font-heading);
    font-size: 1.05rem;
    color: var(--gold);
}

/* Card description */
.community-card-desc {
    font-size: 0.88rem;
    color: var(--muted);
    line-height: 1.7;
    flex: 1;                           /* Takes remaining space, pushing button to bottom */
}

/* Subscription tiers info card — wider, centred */
.sub-info-card {
    background-color: var(--bg-card);
    border: 1px solid rgba(212, 130, 26, 0.5);
    border-radius: var(--radius-lg);
    padding: var(--space-xl);
    text-align: center;
    margin-bottom: var(--space-xl);
    box-shadow:
        0 0 30px rgba(212, 130, 26, 0.08),
        inset 0 0 40px rgba(212, 130, 26, 0.03);
    background-image: radial-gradient(ellipse at top, rgba(212, 130, 26, 0.06) 0%, transparent 60%);
}
.sub-info-title {
    font-size: 1.3rem;
    margin-bottom: var(--space-md);
}
.sub-info-text {
    color: var(--cream);
    font-size: 0.95rem;
    line-height: 1.9;
    margin-bottom: var(--space-lg);
}
.sub-info-text strong {
    color: var(--gold);
}

/* Contact info block at the bottom of the community section */
.contact-info {
    text-align: center;
    padding: var(--space-lg) var(--space-md);
    border-top: 1px solid var(--border);
}
.contact-label {
    font-family: var(--font-heading);
    color: var(--gold);
    font-size: 1rem;
    margin-bottom: var(--space-sm);
}
.contact-item {
    color: var(--muted);
    font-size: 0.9rem;
    margin-bottom: var(--space-xs);
}
.contact-value {
    color: var(--cream);
    font-weight: 500;
}
.contact-link {
    color: var(--amber);
    transition: color 0.2s;
}
.contact-link:hover {
    color: var(--gold);
}


/* ================================================================
   13. SETUP SECTION
   ================================================================
   Adventurer's equipment log styled as a warm parchment card.
   Two-column grid of gear items.
================================================================ */

/* Outer card wrapper */
.setup-card {
    background-color: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: var(--space-xl);
    max-width: 900px;
    margin: 0 auto;
    background-image: radial-gradient(ellipse at top, rgba(212, 130, 26, 0.05) 0%, transparent 60%);
    box-shadow: 0 8px 40px rgba(0, 0, 0, 0.35);
}

/* "— Equipment Log —" header label */
.setup-card-header {
    text-align: center;
    font-family: var(--font-heading);
    color: var(--amber);
    font-size: 0.82rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    margin-bottom: var(--space-xl);
    opacity: 0.65;
}

/* Two-column grid for the gear items */
.setup-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;   /* Two equal columns */
}

/* Individual gear row */
.gear-item {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    padding: 0.9rem var(--space-lg);
    border-bottom: 1px solid var(--border);
    transition: background-color 0.2s;
}
.gear-item:hover {
    background-color: rgba(212, 130, 26, 0.04); /* Very faint amber tint on hover */
}

/*
    Right border on left-column items (odd-numbered).
    :nth-child(odd) targets the 1st, 3rd, 5th, etc. element.
    These are the left column items in a 2-column grid.
*/
.gear-item:nth-child(odd) {
    border-right: 1px solid var(--border);
}

/* The last row's bottom border looks odd if only one item — remove it */
.gear-item:nth-last-child(1),
.gear-item:nth-last-child(2) {
    border-bottom: none;
}

/* Spans the last item across both columns when it's alone */
.gear-item-full {
    grid-column: 1 / -1;              /* From column 1 to the last column */
    border-right: none !important;    /* Override the odd-child rule above */
    border-top: 1px solid var(--border);
}

/* Category label (CPU, GPU, etc.) in amber */
.gear-category {
    font-size: 0.7rem;
    color: var(--amber);
    font-weight: 600;
    letter-spacing: 0.07em;
    text-transform: uppercase;
}

/* Gear name in cream */
.gear-name {
    font-size: 0.92rem;
    color: var(--cream);
    line-height: 1.4;
}


/* ================================================================
   14. FOOTER
================================================================ */

.footer {
    background-color: rgba(0, 0, 0, 0.35);
    border-top: 1px solid var(--border);
    padding: var(--space-lg);
    text-align: center;
}
.footer-text {
    color: var(--muted);
    font-size: 0.85rem;
}


/* ================================================================
   14b. ALTERNATING SECTION LAYOUTS
   ================================================================
   THE CONCEPT — "WINDING PATH" RHYTHM:
   ─────────────────────────────────────────────────────────────────
   Instead of every section centering everything the same way, the
   page alternates left / right / left / right for headings and
   layout focus. This mirrors the feel of a winding forest path —
   you round each corner to find something composed differently.

   IMPLEMENTATION:
   ─────────────────────────────────────────────────────────────────
   Each section uses a modifier class on its title:
     .section-title-left  — wooden sign anchored to the left edge
     .section-title-right — wooden sign anchored to the right edge
     (no modifier = default centered, used for About)

   Multi-column sections use a .xxx-layout grid or flex container
   whose child order and alignment create the left/right emphasis.

   ON MOBILE (≤768px): all alternating layouts collapse back to
   centered single-column — the rhythm is a desktop concept and
   stacking is cleaner at narrow widths.
================================================================ */

/* ── SECTION BLOCK — self-contained alternating unit ───────────── */
/*
    HOW THE ALTERNATING RHYTHM WORKS:
    ─────────────────────────────────────────────────────────────────
    Each section wraps its title + content in a .section-block div.
    The block is capped at 85% of the container width. The remaining
    15% becomes empty space — on the left for right-aligned blocks,
    on the right for left-aligned blocks.

    This is achieved with a single margin trick:
      .block-left  → margin-right: auto  (browser fills space on the right)
      .block-right → margin-left: auto   (browser fills space on the left)

    The section title stays centred ABOVE its own content — it's the
    whole block that shifts, not individual elements within it.

    On mobile, all blocks revert to 100% width centered (see media query).
*/
.section-block {
    max-width: 85%;
}

/* Block anchored to the left — space appears on the right */
.block-left {
    margin-left: 0;
    margin-right: auto;
}

/* Block anchored to the right — space appears on the left */
.block-right {
    margin-left: auto;
    margin-right: 0;
}

/* ── SECTION TITLE ALIGNMENT VARIANTS ──────────────────────────── */

/*
    Left-aligned wooden sign:
    Remove the right auto-margin that centres it; keep margin-right: 0 so
    the sign hugs the left edge of the container.
*/
.section-title-left {
    margin-left: 0;
    margin-right: auto;
    text-align: left;
}

/*
    Right-aligned wooden sign:
    Swap — remove left auto-margin, push the sign to the right edge.
*/
.section-title-right {
    margin-left: auto;
    margin-right: 0;
    text-align: right;
}

/* Subtitle alignment to match heading */
.section-subtitle-left  { text-align: left; }
.section-subtitle-right { text-align: right; }

/* ── BREATHING ROOM ─────────────────────────────────────────────── */
/*
    Increase vertical padding so sections feel like generous open spaces
    rather than tight stacked boxes. 6rem ≈ 96px top and bottom.
*/
.section {
    padding: 6rem var(--space-lg);
}

/* ── ABOUT — TWO COLUMN ─────────────────────────────────────────── */
/*
    40% / 60% grid split:
    Left column (40%): profile image, name, milestone timeline
    Right column (60%): Adventurer's Profile character card

    align-items: start — columns anchor to their tops, not stretched
    to match the taller sibling.
*/
.about-layout {
    display: grid;
    grid-template-columns: 40% 1fr;
    gap: var(--space-xl);
    align-items: start;
    margin-top: var(--space-xl);
}

/* Left column: centred flex stack for the image → name → timeline */
.about-left {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-md);
}

/* Circular profile image, smaller than the hero version */
.about-profile-img {
    width: 130px;
    height: 130px;
    border-radius: 50%;
    object-fit: cover;
    border: 3px solid var(--amber);
    box-shadow:
        0 0 20px rgba(212, 130, 26, 0.4),
        0 0 50px rgba(212, 130, 26, 0.15);
    display: block;
}

/* Name text below the image */
.about-name {
    font-family: var(--font-heading);
    color: var(--gold);
    font-size: 1rem;
    text-align: center;
    font-weight: 700;
}

/* ── SCHEDULE — LEFT HEADING + DECORATIVE EMOJI ─────────────────── */
/*
    Flex row: heading group on the left, large decorative 🌰 on the right.
    The emoji acts as a visual counterweight — left text, right ornament.
*/
.schedule-section-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-lg);
    margin-bottom: var(--space-xl);
}

/* The heading + subtitle sit together in a flex column */
.schedule-heading-group {
    flex: 1;
}
.schedule-heading-group .section-title-left {
    margin-bottom: var(--space-sm);
}
.schedule-heading-group .section-subtitle-left {
    margin-bottom: 0; /* Outer container provides the spacing */
}

/* Large decorative acorn — floated to the right as a counterbalance */
.schedule-deco-emoji {
    font-size: 4.5rem;
    line-height: 1;
    opacity: 0.7;
    flex-shrink: 0;
    /*
        translateY nudges it down so it optically aligns with the
        midpoint of the heading text block rather than the top.
    */
    transform: translateY(8px);
    filter: drop-shadow(0 4px 8px rgba(212, 130, 26, 0.3));
}

/* ── STREAM — LEFT HEADING, RIGHT BADGE + BUTTON ─────────────────── */
/*
    Flex row: heading on the left, actions (badge + button) on the right.
    justify-content: space-between pushes them to opposite edges.
    flex-wrap: wrap so they stack on narrow screens before the media query.
    align-items: center vertically centres the badge with the sign height.
*/
.stream-top-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--space-md);
    margin-bottom: var(--space-lg);
}

/* Badge and button sit together on the right */
.stream-actions {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    flex-shrink: 0;
}

/* The section title inside .stream-top-bar needs its own margin reset —
   the left-aligned wooden sign would otherwise auto-margin conflict with flex */
.stream-top-bar .section-title-left {
    margin: 0;
}

/* ── NUTDEX — CARD LEFT, TEXT RIGHT ─────────────────────────────── */
/*
    Two-column grid: the TCG card on the left (40%), descriptive
    text + heading right-aligned on the right (60%).
    align-items: center — card and text block align vertically to midpoint.
*/
.nutdex-layout {
    display: grid;
    grid-template-columns: 40% 1fr;
    gap: var(--space-xl);
    align-items: center;
}

/* Text column: right-align everything */
.nutdex-layout-text {
    display: flex;
    flex-direction: column;
    align-items: flex-end;  /* Right-align children (heading, subtitle, note) */
    gap: var(--space-md);
    text-align: right;
}
.nutdex-layout-text .section-subtitle-right,
.nutdex-layout-text .nutdex-note {
    text-align: right;
    margin-bottom: 0;
}

/* Card column: centre the card within its column */
.nutdex-layout-card {
    display: flex;
    justify-content: center;
}

/* ── COMMUNITY — SUB-INFO CARD TWO COLUMNS ──────────────────────── */
/*
    The subscription info card splits into two horizontal halves:
    Left: tier info text (title + description)
    Right: Subscribe button, visually prominent on its own
*/
.sub-info-two-col {
    display: flex;
    align-items: center;
    gap: var(--space-xl);
}

/* Left: text content, left-aligned within the card */
.sub-info-col-left {
    flex: 1;
    text-align: left;
}
.sub-info-col-left .sub-info-title {
    text-align: left;
    margin-bottom: var(--space-md);
}
.sub-info-col-left .sub-info-text {
    text-align: left;
    margin-bottom: 0;
}

/* Right: button column, centred and given a minimum width */
.sub-info-col-right {
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-md);
    min-width: 180px;
}

/* ── SETUP — TAGLINE LEFT, HEADING RIGHT ─────────────────────────── */
/*
    Flex row: "The tools of the trade ⚔️" tagline on the left,
    the wooden sign heading on the right.
    The tagline acts as a teaser — you read left first, then find
    the section name on the right.
*/
.setup-section-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--space-lg);
    margin-bottom: var(--space-xl);
}

/* Tagline — muted, italic, smaller than the wooden sign heading */
.setup-tagline {
    color: var(--muted);
    font-style: italic;
    font-size: 1rem;
    font-family: var(--font-heading);
}

/* The heading inside the flex row needs its margin reset */
.setup-section-header .section-title-right {
    margin: 0;
}


/* ================================================================
   15. ANIMATIONS — SCROLL FADE-IN
   ================================================================
   JavaScript's Intersection Observer watches elements with
   the class "fade-in-section". When they scroll into view,
   JS adds the class "visible".

   These CSS rules define WHAT happens before and after.
================================================================ */

/*
    INITIAL STATE (before visible):
    - opacity: 0 = completely invisible
    - transform: translateY(30px) = shifted 30px downward
    - transition: animate changes smoothly over 0.7 seconds
*/
.fade-in-section {
    opacity: 0;
    transform: translateY(30px);
    transition: opacity 0.7s ease, transform 0.7s ease;
}

/*
    VISIBLE STATE (after JS adds "visible" class):
    - opacity: 1 = fully visible
    - transform: none = back in its normal position
    The transition above animates both changes smoothly.
*/
.fade-in-section.visible {
    opacity: 1;
    transform: translateY(0);
}


/* ================================================================
   15b. SPRING SCROLL ANIMATIONS
   ================================================================
   Cards and grid items slide in from the side when they scroll
   into view, overshoot their final position, and spring back —
   like a physical object bouncing against a cushion.

   HOW THE CUBIC-BEZIER SPRING WORKS:
   ─────────────────────────────────────────────────────────────────
   A CSS cubic-bezier() timing function is defined by four numbers:
   cubic-bezier(x1, y1, x2, y2)

   These describe two "control points" that shape a curve between
   the start (0,0) and end (1,1) of the animation.

   The Y axis represents how far through the animation we are.
   Normally Y stays between 0 and 1. But when Y EXCEEDS 1, the
   animation overshoots past its final value — creating a bounce.

   cubic-bezier(0.34, 1.56, 0.64, 1)
                ─┬──  ─┬──  ─┬──  ─┬─
                 │     │     │     └── end Y = 1 (pulls back to target)
                 │     │     └──────── end X = 0.64 (late phase)
                 │     └────────────── start Y = 1.56 ← OVERSHOOT
                 └──────────────────── start X = 0.34 (early phase)

   The y1=1.56 control point pulls the animation ABOVE the final
   value mid-flight. The value "comes back down" to 1.0 at the end,
   creating the springy overshoot effect.

   For transforms, overshooting means:
   - A translateX(0) target might momentarily go to translateX(8px)
     before settling — the element bounces slightly past its rest position.

   FLOW:
   1. JS adds .animate-from-left / -right / -bottom → element hides (opacity:0)
   2. IntersectionObserver fires → JS adds .spring-in → spring transition plays
   3. Element slides in, overshoots, springs back to final position
================================================================ */

/* ── STARTING STATES — element hidden and offset ────────────────── */
/*
    transition: none on the initial state is critical.
    Without it, adding the class itself would trigger a transition
    from the browser's default values, causing an unintended flash.
    We only want the transition to play when .spring-in is added.
*/
.animate-from-left {
    opacity: 0;
    transform: translateX(-80px);
    transition: none;
}
.animate-from-right {
    opacity: 0;
    transform: translateX(80px);
    transition: none;
}
.animate-from-bottom {
    opacity: 0;
    transform: translateY(60px);
    transition: none;
}

/* ── TRIGGERED STATE — spring into final position ────────────────── */
/*
    When JS adds .spring-in, the transition kicks in.
    opacity uses a simple ease (no overshoot needed for fading).
    transform uses the spring cubic-bezier that creates the bounce.

    The two transitions are comma-separated — each property gets
    its own duration and easing independently.
*/
.animate-from-left.spring-in {
    opacity: 1;
    transform: translateX(0);
    transition:
        opacity 0.6s ease,
        transform 0.8s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.animate-from-right.spring-in {
    opacity: 1;
    transform: translateX(0);
    transition:
        opacity 0.6s ease,
        transform 0.8s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.animate-from-bottom.spring-in {
    opacity: 1;
    transform: translateY(0);
    transition:
        opacity 0.6s ease,
        transform 0.8s cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* ── STAGGER — children animate one after another ────────────────── */
/*
    nth-child selects elements by their position among siblings.
    Adding a transition-delay makes later siblings start after earlier ones.
    This creates a ripple effect across rows of cards.
    The delay only activates once .spring-in is present (the animation state).
*/
.animate-from-left:nth-child(2).spring-in,
.animate-from-right:nth-child(2).spring-in { transition-delay: 0.1s; }

.animate-from-left:nth-child(3).spring-in,
.animate-from-right:nth-child(3).spring-in { transition-delay: 0.2s; }

.animate-from-left:nth-child(4).spring-in,
.animate-from-right:nth-child(4).spring-in { transition-delay: 0.3s; }

/* ── MOBILE — disable animations for performance ─────────────────── */
/*
    On small screens, spring animations can feel jarring and hurt
    performance on low-powered devices. We bypass all of them by
    forcing the final visible state immediately.
*/
@media (max-width: 768px) {
    .animate-from-left,
    .animate-from-right,
    .animate-from-bottom {
        opacity: 1;
        transform: none;
        transition: none;
    }
}


/* ================================================================
   15c. VINE DECORATIONS
   ================================================================
   Decorative SVG vines climb both sides of the page, fixed to the
   viewport edges. They are purely visual — z-index: 0 keeps them
   behind all content, and pointer-events: none makes them invisible
   to mouse and touch interactions.

   HOW THE SVG VINES ARE BUILT:
   ─────────────────────────────────────────────────────────────────
   Each vine is an SVG with viewBox="0 0 80 800" — an 80×800 unit
   coordinate space. This maps 1:1 to the 80px wide CSS container.

   THE STEM — <path d="M ... C ... C ...">
   The stem uses cubic Bezier curves (C command) to create organic
   winding. Each C command is:
     C cx1 cy1, cx2 cy2, x y
     - cx1/cy1: first control point (pulls curve from start)
     - cx2/cy2: second control point (pulls curve at end)
     - x/y: the endpoint

   By alternating the control points left and right of the 40px
   centre line, the stem winds naturally back and forth.

   THE LEAVES — <ellipse>
   Each leaf is an ellipse with:
   - cx/cy positioned near the stem at regular intervals
   - rx/ry giving a wide-flat leaf shape (leaf is wider than tall)
   - transform="rotate(angle cx cy)" tilts each leaf at a different
     angle so they look natural, not stamped from a template
   - opacity varies slightly to suggest depth and age

   THE FLOWERS — <circle>
   Small circles in amber/gold scattered at intervals along the stem.
   Low opacity (0.2–0.25) keeps them subtle — just a hint of warmth.

   MIRRORING: the right vine uses the same shapes but with x
   coordinates flipped around the 40px centre (cx → 80 - cx),
   and rotation angles negated, so it's a natural mirror.
================================================================ */

.vine-left,
.vine-right {
    position: fixed;           /* Stays pinned to screen edges during scroll */
    top: 0;
    width: 80px;
    height: 100vh;             /* Full viewport height */
    pointer-events: none;      /* Clicks and touches pass straight through */
    z-index: 0;                /* Below all page content (content uses z-index ≥ 1) */
    overflow: hidden;
}
.vine-left  { left: 0; }
.vine-right { right: 0; }

/* SVG fills the container exactly */
.vine-left svg,
.vine-right svg {
    width: 100%;
    height: 100%;
}

/*
    Hide vines on screens narrower than 1200px.
    Below this width, section content expands to use more of the
    viewport and the vines would overlap it.
*/
@media (max-width: 1200px) {
    .vine-left,
    .vine-right {
        display: none;
    }
}


/* ================================================================
   16. RESPONSIVE STYLES — MOBILE
   ================================================================
   @media queries apply styles ONLY when certain conditions are met.

   max-width: 900px = applies when the screen is 900px or narrower.
   max-width: 600px = applies when the screen is 600px or narrower.
   max-width: 480px = applies for small phones.

   These OVERRIDE the desktop styles above, adapting the layout
   for smaller screens.
================================================================ */

@media (max-width: 900px) {

    /* SCHEDULE: 4 columns on medium screens instead of 7 */
    .schedule-grid {
        grid-template-columns: repeat(4, 1fr);
    }

    /* STREAM: stack vertically and give fixed heights */
    .stream-container {
        flex-direction: column;        /* Stack items vertically instead of side by side */
        height: auto;                  /* Remove fixed height, let content dictate */
    }
    .stream-player {
        height: 320px;
    }
    .stream-chat {
        flex: none;                    /* Stop it growing/shrinking */
        height: 400px;
        min-width: unset;
    }

    /* SETUP: single column on medium screens */
    .setup-grid {
        grid-template-columns: 1fr;
    }
    .gear-item:nth-child(odd) {
        border-right: none;            /* No right border needed in single column */
    }
    .gear-item:nth-last-child(1),
    .gear-item:nth-last-child(2) {
        border-bottom: 1px solid var(--border); /* Restore borders in single column */
    }
    .gear-item:last-child {
        border-bottom: none;
    }
    .gear-item-full {
        grid-column: auto;             /* Remove the span in single-column layout */
        border-top: none;
    }
}

@media (max-width: 768px) {

    /* ── NAVBAR ─────────────────────────────────────── */

    /* Show the hamburger button on mobile */
    .hamburger {
        display: block;
    }

    /*
        MOBILE NAV DROPDOWN
        ─────────────────────
        Hide the nav links by default on mobile.
        When the hamburger is clicked, JS adds the "open" class,
        which triggers the .nav-links.open rule below.

        The wooden button images stack vertically in the dropdown.
        We centre them horizontally with align-items: center.
    */
    .nav-links {
        display: none;
        position: absolute;            /* Pop out below the navbar */
        top: 64px;
        left: 0;
        right: 0;
        background-color: rgba(22, 20, 8, 0.98); /* Matches navbar wood grain base (#161408) */
        backdrop-filter: blur(12px);
        flex-direction: column;        /* Stack image buttons vertically */
        align-items: center;           /* Centre buttons horizontally */
        padding: var(--space-lg) var(--space-md);
        gap: 10px;                     /* Slightly more gap for touch-friendly spacing */
        border-bottom: 1px solid var(--border);
    }

    /* When hamburger is clicked, JS adds .open to show the menu */
    .nav-links.open {
        display: flex;
    }

    /*
        Make the wooden buttons slightly larger in the mobile dropdown.
        Bigger tap targets are easier to press on touchscreens.
        We scale up from the 148×38px desktop size to 180×46px.
    */
    .nav-link {
        width: 180px;
        height: 46px;
    }

    /* Allow the navbar to show the dropdown below it */
    .navbar {
        overflow: visible;
    }

    /* ── HERO ────────────────────────────────────────── */
    .hero-avatar {
        width: 130px;
        height: 130px;
    }
    .hero-buttons {
        flex-direction: column;
        align-items: center;
    }
    .hero-milestones {
        flex-direction: column;
        align-items: center;
    }

    /* ── ABOUT ───────────────────────────────────────── */
    .character-card {
        padding: var(--space-lg);
    }
    /* Stack stat rows on mobile — dotted line doesn't work vertically */
    .stat-row {
        flex-direction: column;
        gap: 0.15rem;
    }
    .stat-dots {
        display: none;                 /* Hide the dot dividers — doesn't make sense stacked */
    }

    /* ── SCHEDULE ────────────────────────────────────── */
    .schedule-grid {
        grid-template-columns: repeat(3, 1fr);
    }

    /* ── COMMUNITY ───────────────────────────────────── */
    .sub-info-card {
        padding: var(--space-lg);
    }

    /* ── SECTIONS ────────────────────────────────────── */
    .section {
        padding: var(--space-xl) var(--space-md);
    }

    /*
        ── ALTERNATING LAYOUT RESETS (mobile)
        ────────────────────────────────────────────────
        All multi-column and alternating layouts collapse
        to a single centred column on screens ≤768px.
        Every alignment modifier also resets to centred.
    */

    /* Section blocks: full width, centred on mobile */
    .section-block {
        max-width: 100%;
        margin-left: auto;
        margin-right: auto;
    }

    /* About — single column, image on top */
    .about-layout {
        grid-template-columns: 1fr;
    }
    .about-left,
    .about-right {
        width: 100%;
    }

    /* Schedule — heading and emoji stack vertically */
    .schedule-section-header {
        flex-direction: column;
        align-items: flex-start;
    }
    .schedule-deco-emoji {
        align-self: flex-end;
        font-size: 3rem;
    }

    /* Stream — actions stack below heading, centred */
    .stream-top-bar {
        flex-direction: column;
        align-items: center;
    }
    .stream-top-bar .section-title-left {
        text-align: center;
        margin: 0 auto;
    }

    /* NutDex — card on top, text below */
    .nutdex-layout {
        grid-template-columns: 1fr;
    }
    .nutdex-layout-text {
        align-items: center;
        text-align: center;
    }
    .nutdex-layout-text .section-subtitle-right,
    .nutdex-layout-text .nutdex-note {
        text-align: center;
    }

    /* Community sub-info — stack vertically */
    .sub-info-two-col {
        flex-direction: column;
        gap: var(--space-lg);
    }
    .sub-info-col-left {
        text-align: center;
    }
    .sub-info-col-left .sub-info-title,
    .sub-info-col-left .sub-info-text {
        text-align: center;
    }

    /* Setup — tagline above heading, both centred */
    .setup-section-header {
        flex-direction: column;
        align-items: center;
        text-align: center;
    }
    .setup-section-header .section-title-right {
        margin: 0 auto;
        text-align: center;
    }

    /* All title alignment modifiers reset to centred on mobile */
    .section-title-left,
    .section-title-right {
        margin: 0 auto;
        text-align: center;
    }
    .section-subtitle-left,
    .section-subtitle-right {
        text-align: center;
    }
}

@media (max-width: 480px) {

    /* SCHEDULE: 2 columns on very small phones */
    .schedule-grid {
        grid-template-columns: repeat(2, 1fr);
    }

    /* Slightly reduce section vertical padding */
    .section {
        padding: var(--space-lg) var(--space-md);
    }

    /* Full-width buttons on tiny screens */
    .hero-buttons .btn {
        width: 100%;
        max-width: 280px;
    }
}
