/* ==========================================================================
   PALETTE — Refined Paper
   The warm printed page, brought up a level. Same paper stock and geometric
   type (Space Grotesk / Inter), but softened and tidied: gently rounded
   surfaces, two-layer shadows for quiet depth, a deeper and calmer document
   blue, and a proper masthead / hero above the two-column body.
   ========================================================================== */

:root {
    /* Paper stock & ink */
    --paper: #f4efe4;        /* the page */
    --paper-raised: #fffdf8; /* card / panel surface */
    --paper-alt: #ebe3d3;    /* recessed tray / inset blocks */
    --ink: #1c1d23;
    --ink-soft: #45464e;     /* body copy */
    --ink-muted: #827c6d;    /* captions, labels, metadata */

    /* Edges & separators — soft, low-contrast, never harsh */
    --rule: #e4ddcc;
    --rule-strong: #d5cbb4;
    --shadow: 0 1px 2px rgba(30, 22, 10, 0.05),
              0 10px 24px -16px rgba(30, 22, 10, 0.16);
    --shadow-lift: 0 2px 6px rgba(30, 22, 10, 0.07),
                   0 20px 44px -20px rgba(30, 22, 10, 0.22);

    /* Accent — a deeper, calmer document blue */
    --accent: #1f52b8;
    --accent-hover: #17408f;
    --accent-soft: #e8effb;
    --accent-ring: rgba(31, 82, 184, 0.28);

    /* Near-black navy slab, used where Minecraft's own §-colors need it */
    --slab-bg: #000215;
    --slab-fg: #e9e7e0;

    /* Semantic marks, muted to sit on paper rather than glow */
    --mark-ok: #2f7d4f;
    --mark-warn: #a8760f;
    --mark-bad: #bb3b2c;
    --mark-ok-soft: #e3f1e6;
    --mark-warn-soft: #f6ecd6;
    --mark-bad-soft: #f7e3df;

    --display: 'Space Grotesk', 'Trebuchet MS', 'Segoe UI', sans-serif;
    --sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    --mono: 'SF Mono', 'Cascadia Code', 'JetBrains Mono', Consolas, Monaco, monospace;

    /* Softened from the old hard 0 — cards and panels now carry a small
       radius, controls and badges go fully pill. */
    --radius: 5px;
    --radius-sm: 3px;
    --radius-pill: 999px;
    --measure: 46rem;
}

/* ==========================================================================
   1. GLOBAL RESETS & PAGE BASE
   ========================================================================== */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: var(--sans);
    background-color: var(--paper);
    /* A whisper of tone so the "paper" reads even flat on screen. */
    background-image:
        radial-gradient(circle at 12% 15%, rgba(31, 82, 184, 0.035), transparent 42%),
        radial-gradient(circle at 88% 6%, rgba(168, 118, 30, 0.045), transparent 40%);
    background-attachment: fixed;
    color: var(--ink-soft);
    font-size: 16.5px;
    line-height: 1.65;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

a {
    color: var(--accent);
    text-decoration: none;
    font-weight: 500;
    transition: color 0.14s ease, background-color 0.14s ease;
}

a:hover {
    color: var(--accent-hover);
    text-decoration: underline;
    text-underline-offset: 0.18em;
    text-decoration-thickness: 1.5px;
}

a:focus-visible {
    outline: 2px solid var(--accent-ring);
    outline-offset: 2px;
}

h1, h2, h3 {
    font-family: var(--display);
    color: var(--ink);
    font-weight: 600;
    letter-spacing: -0.01em;
}

/* ==========================================================================
   2. MASTHEAD
   ========================================================================== */
header {
    background-color: rgba(244, 239, 228, 0.82);
    backdrop-filter: saturate(180%) blur(10px);
    -webkit-backdrop-filter: saturate(180%) blur(10px);
    border-bottom: 1px solid var(--rule);
    position: sticky;
    top: 0;
    z-index: 100;
    width: 100%;
}

nav {
    max-width: 64rem;
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.9rem 2rem;
    gap: 1.5rem;
    /* Let the status badge react to how much room the bar actually has. */
    container: nav / inline-size;
}

.logo {
    font-family: var(--display);
    font-size: 1.15rem;
    font-weight: 600;
    color: var(--ink);
    letter-spacing: -0.01em;
}

.logo:hover {
    color: var(--ink);
    text-decoration: none;
}

.nav-status {
    display: flex;
    align-items: center;
    gap: 0.7rem;
}

/* Status is a soft pill tag, tinted by state. */
.status-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.28rem 0.7rem;
    border-radius: var(--radius-pill);
    background-color: var(--mark-ok-soft);
    color: var(--mark-ok);
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    /* Never break "Status: Alive!" across two lines — collapse to the short
       label instead (see the container query below). */
    white-space: nowrap;
}

/* Full phrase by default; the one-word version only when the bar is cramped. */
.status-text-short {
    display: none;
}

@container nav (max-width: 30rem) {
    .status-text-full {
        display: none;
    }

    .status-text-short {
        display: inline;
    }
}

.status-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background-color: currentColor;
    box-shadow: 0 0 0 3px color-mix(in srgb, currentColor 22%, transparent);
}

/* Deployment id — a quiet mono chip. */
.status-label {
    font-family: var(--mono);
    font-size: 0.68rem;
    color: var(--ink-muted);
    letter-spacing: 0.02em;
    background-color: var(--paper-raised);
    border: 1px solid var(--rule);
    border-radius: var(--radius-pill);
    padding: 0.2rem 0.6rem;
}

/* ==========================================================================
   3. THE PAGE BODY
   ========================================================================== */
main {
    flex: 1;
    width: 100%;
    max-width: 64rem;
    margin: 0 auto;
    padding: 3.5rem 2rem 5rem;
}

/* --- Hero / masthead intro ---------------------------------------------- */
.hero {
    margin-bottom: 3.25rem;
}

.eyebrow {
    font-family: var(--mono);
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--ink-muted);
    margin-bottom: 0.8rem;
}

h1 {
    font-size: 2.7rem;
    font-weight: 600;
    line-height: 1.08;
    letter-spacing: -0.02em;
}

.hero .sub {
    margin-top: 1.15rem;
    font-size: 1.05rem;
    line-height: 1.6;
    color: var(--ink-soft);
    max-width: 34rem;
    text-wrap: pretty;
}

.hero .links {
    margin-top: 1.4rem;
    display: flex;
    gap: 1.2rem;
    font-size: 0.85rem;
}

.hero .links a {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-weight: 500;
}

/* ==========================================================================
   4. SET-OFF TEXT — code and quoted matter
   ========================================================================== */
.hero-code {
    margin-top: 2rem;
}

pre {
    background-color: var(--paper-alt);
    border: 1px solid var(--rule);
    border-radius: var(--radius-sm);
    padding: 1rem 1.1rem;
    overflow-x: auto;
    margin: 1.5rem 0;
}

code {
    font-family: var(--mono);
    font-size: 0.82rem;
    line-height: 1.6;
    color: var(--ink);
}

.keyword   { color: #7a2f8a; font-weight: 600; }
.string    { color: #8a5a12; }
.function  { color: var(--accent); }
.class     { color: #2f6b3a; }
.module    { color: var(--ink-muted); }
.variable  { color: #a03328; }
.decorator { color: #6a3894; }

/* ==========================================================================
   5. TWO-COLUMN LAYOUT — selected work (left) + status rail (right)
   ========================================================================== */
.layout {
    display: grid;
    grid-template-columns: 1fr 21rem;
    gap: 3rem;
    align-items: start;
}

.projects-col {
    min-width: 0;
}

/* Section running head: small-caps label, leading accent bar, trailing rule. */
.section-head {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    font-family: var(--display);
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--ink-muted);
    padding-bottom: 0.7rem;
}

.section-head::before {
    content: "";
    flex: 0 0 auto;
    width: 0.7rem;
    height: 3px;
    border-radius: var(--radius-pill);
    background-color: var(--accent);
}

.section-head::after {
    content: "";
    flex: 1;
    height: 1px;
    background-color: var(--rule);
}

.section-note {
    font-size: 0.9rem;
    color: var(--ink-muted);
    margin: 0.2rem 0 0.6rem;
}

/* --- Left column: the project list ----------------------------------------
   Each entry is a compact GitHub-repo-style row: octicon + owner/name link,
   a language dot, a one-line blurb, and the stack. Lifts a little on hover. */
.projects {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.projects .section-note {
    margin-bottom: 0.4rem;
}

.project {
    background-color: var(--paper-raised);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    padding: 0.95rem 1.1rem;
    box-shadow: var(--shadow);
    transition: transform 0.16s ease, box-shadow 0.16s ease, border-color 0.16s ease;
}

.project:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-lift);
    border-color: var(--rule-strong);
}

.project-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.repo-mark {
    flex: 0 0 auto;
    color: var(--ink-muted);
}

.project-name {
    font-family: var(--mono);
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--accent);
    margin-right: auto;
    word-break: break-all;
}

.project-name:hover {
    color: var(--accent-hover);
    text-decoration: underline;
}

.repo-owner {
    color: var(--ink-muted);
    font-weight: 400;
}

/* Language indicator: GitHub's coloured dot + name. */
.project-lang {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.72rem;
    color: var(--ink-muted);
    white-space: nowrap;
}

.lang-dot {
    width: 9px;
    height: 9px;
    flex: 0 0 auto;
    border-radius: 50%;
    background-color: var(--rule-strong);
}

.lang-python     { background-color: #3572a5; }
.lang-javascript { background-color: #f1e05a; }

/* Focus line — a small accent pill. */
.project-focus {
    display: inline-block;
    margin: 0.55rem 0 0;
    padding: 0.16rem 0.5rem;
    font-size: 0.62rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--accent-hover);
    background-color: var(--accent-soft);
    border-radius: var(--radius-pill);
}

.project-desc {
    font-size: 0.88rem;
    line-height: 1.55;
    color: var(--ink-soft);
    margin: 0.5rem 0 0.55rem;
    max-width: 42rem;
    text-wrap: pretty;
}

.project .stack {
    font-family: var(--mono);
    font-size: 0.72rem;
    color: var(--ink-muted);
    margin: 0;
}

/* "See more" toggle + scrollable overflow -------------------------------
   The extra project cards live in the .projects section but are hidden
   until "See more" is pressed. On expand the section is frozen at its
   current height (set inline by JS) and switches to overflow-y: scroll,
   so the extra cards are reached by scrolling rather than by the element
   growing on the page. A sticky chevron hints that more can be scrolled. */
.see-more {
    align-self: center;
    margin-top: 0.25rem;
    padding: 0.42rem 0.95rem;
    font-family: var(--display);
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--accent);
    background-color: var(--paper-raised);
    border: 1px solid var(--rule-strong);
    border-radius: var(--radius-pill);
    cursor: pointer;
    transition: border-color 0.16s ease, color 0.16s ease;
}

.see-more:hover {
    color: var(--accent-hover);
    border-color: var(--accent-ring);
}

.project-extra {
    display: none;
}

.projects.is-expanded {
    overflow-y: scroll;
    scroll-behavior: smooth;
    /* room so the last card clears the sticky chevron */
    padding-bottom: 2.4rem;
    /* Firefox */
    scrollbar-width: thin;
    scrollbar-color: var(--rule-strong) var(--paper-alt);
}

/* WebKit / Blink — paper-toned scrollbar matching the cards. */
.projects.is-expanded::-webkit-scrollbar {
    width: 10px;
}

.projects.is-expanded::-webkit-scrollbar-track {
    background-color: var(--paper-alt);
    border-left: 1px solid var(--rule);
}

.projects.is-expanded::-webkit-scrollbar-thumb {
    background-color: var(--rule-strong);
    border: 2px solid var(--paper-alt);
    border-radius: var(--radius-pill);
}

.projects.is-expanded::-webkit-scrollbar-thumb:hover {
    background-color: var(--ink-muted);
}

.projects.is-expanded .project-extra {
    display: block;
}

/* Sticky scroll affordance pinned to the bottom of the scroll area. */
.scroll-hint {
    display: none;
}

.projects.is-expanded .scroll-hint {
    display: flex;
    position: sticky;
    bottom: 0;
    align-self: center;
    justify-content: center;
    align-items: center;
    width: 1.9rem;
    height: 1.9rem;
    margin-top: -1.9rem;
    border-radius: var(--radius-pill);
    /* Solid accent chip with a white chevron: clearly legible against the
       cards, still small enough to read as a quiet affordance. */
    color: #fff;
    background-color: var(--accent);
    border: 1px solid rgba(28, 24, 17, 0.15);
    /* Soft dark halo + a feathered paper glow that melts into the list
       instead of a hard ring. */
    box-shadow:
        0 6px 16px rgba(28, 24, 17, 0.5),
        0 16px 40px -6px rgba(28, 24, 17, 0.55),
        0 24px 60px -12px rgba(28, 24, 17, 0.4),
        0 0 0 2px var(--paper),
        0 0 6px 5px var(--paper);
    animation: scroll-hint-bob 1.4s ease-in-out infinite;
    transition: opacity 0.2s ease;
}

.projects.is-expanded .scroll-hint.is-hidden {
    opacity: 0;
    pointer-events: none;
}

@keyframes scroll-hint-bob {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(3px); }
}

/* --- Right column: the status rail --------------------------------------
   Set into a recessed, slightly darker tray so it reads as a distinct
   sidebar; the panels inside sit raised and lighter against it. */
.rail {
    display: flex;
    flex-direction: column;
    gap: 1.1rem;
    position: sticky;
    top: 5rem;
    padding: 1.1rem;
    background-color: var(--paper-alt);
    border: 1px solid var(--rule-strong);
    border-radius: var(--radius);
    box-shadow: inset 0 1px 4px rgba(30, 22, 10, 0.08);
}

.rail .section-head {
    margin-bottom: -0.2rem;
}

.rail .section-head::after {
    background-color: var(--rule-strong);
}

.rail-panel {
    background-color: var(--paper-raised);
    border: 1px solid var(--rule-strong);
    border-radius: var(--radius);
    padding: 1.15rem 1.2rem;
    box-shadow: var(--shadow);
}

.rail .mc-basic-stats {
    flex-wrap: wrap;
    row-gap: 0.35rem;
}

@media (max-width: 880px) {
    .layout {
        grid-template-columns: 1fr;
        gap: 2.5rem;
    }

    .rail {
        position: static;
    }
}

/* ==========================================================================
   5a. LEGACY CARD RUN — retained for any stacked .card entries
   ========================================================================== */
.cards {
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
}

.card {
    background-color: var(--paper-raised);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    padding: 1.35rem 1.4rem;
    box-shadow: var(--shadow);
}

.card h3 {
    font-size: 1.15rem;
    font-weight: 600;
    color: var(--ink);
    margin-bottom: 0.35rem;
}

.card > p {
    color: var(--ink-soft);
    font-size: 0.95rem;
    margin-bottom: 0.6rem;
    max-width: 34rem;
}

.card a {
    font-size: 0.95rem;
}

.is-hidden {
    display: none !important;
}

/* ==========================================================================
   5b. MINECRAFT SERVER STATUS ENTRY
   ========================================================================== */
.card-mc {
    display: flex;
    flex-direction: column;
}

/* Upper block: identity, players / version / last-updated. */
.mc-basic {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
}

.mc-top {
    display: flex;
    align-items: center;
    gap: 0.7rem;
}

.mc-icon-wrap {
    width: 36px;
    height: 36px;
    flex: 0 0 auto;
    overflow: hidden;
    border-radius: var(--radius-sm);
    border: 1px solid var(--rule-strong);
}

.mc-icon {
    width: 100%;
    height: 100%;
    image-rendering: pixelated;
    display: block;
}

.mc-icon-fallback {
    width: 100%;
    height: 100%;
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 1fr 1fr;
}

.mc-icon-fallback span:nth-child(1) { background: #6a994e; }
.mc-icon-fallback span:nth-child(2) { background: #386641; }
.mc-icon-fallback span:nth-child(3) { background: #7f5539; }
.mc-icon-fallback span:nth-child(4) { background: #9c6644; }

.mc-title-row {
    display: flex;
    align-items: center;
    /* Tight row-gap so a wrapped badge sits right under the name, not adrift. */
    gap: 0.3rem 0.5rem;
    min-width: 0;
    flex-wrap: wrap;
}

.mc-title-row h3 {
    font-size: 1.02rem;
    line-height: 1.2;
    margin-bottom: 0;
}

/* "Copy IP" button — sits inline next to the status badge. */
.mc-copy {
    flex: 0 0 auto;
    padding: 0.2rem 0.55rem;
    font-family: var(--display);
    font-size: 0.62rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--accent);
    background-color: var(--paper-raised);
    border: 1px solid var(--rule-strong);
    border-radius: var(--radius-pill);
    cursor: pointer;
    transition: color 0.14s ease, border-color 0.14s ease, background-color 0.14s ease;
}

.mc-copy:hover {
    color: var(--accent-hover);
    border-color: var(--accent-ring);
}

.mc-copy.is-copied {
    color: var(--mark-ok);
    border-color: var(--mark-ok);
    background-color: var(--mark-ok-soft);
}

/* Pill badges, tinted by state. */
.mc-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.22rem 0.6rem;
    border-radius: var(--radius-pill);
    font-size: 0.66rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.07em;
}

.mc-badge.is-online  { color: var(--mark-ok);   background-color: var(--mark-ok-soft); }
.mc-badge.is-warning { color: var(--mark-warn); background-color: var(--mark-warn-soft); }
.mc-badge.is-offline { color: var(--mark-bad);  background-color: var(--mark-bad-soft); }

/* Stats line: players / version left, last-updated right. */
.mc-basic-stats {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
}

.mc-stats {
    display: flex;
    font-size: 0.78rem;
    color: var(--ink-muted);
    white-space: nowrap;
}

.mc-stat + .mc-stat::before {
    content: '·';
    margin: 0 0.5rem;
    color: var(--rule-strong);
}

.mc-stat-label {
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-size: 0.66rem;
}

.mc-stat-value {
    font-weight: 600;
    color: var(--ink);
}

.mc-meta {
    flex: 0 0 auto;
    font-size: 0.7rem;
    font-style: italic;
    color: var(--ink-muted);
    white-space: nowrap;
}

/* Lower block: host-level detail from the Cybrancee (Pterodactyl) panel.
   Its top border is the divider between the two halves of the card. */
.mc-host {
    display: flex;
    flex-direction: column;
    gap: 0.65rem;
    margin-top: 0.95rem;
    padding-top: 0.95rem;
    border-top: 1px solid var(--rule-strong);
}

.mc-res {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

.mc-res-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.6rem;
}

.mc-res-label {
    font-size: 0.62rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--ink-muted);
}

.mc-res-value {
    font-family: var(--mono);
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--ink);
}

.mc-meter {
    height: 5px;
    background-color: var(--paper-alt);
    border: 1px solid var(--rule);
    border-radius: var(--radius-pill);
    overflow: hidden;
}

.mc-meter span {
    display: block;
    width: 0;
    height: 100%;
    border-radius: var(--radius-pill);
    background-color: var(--accent);
    transition: width 0.3s ease, background-color 0.2s ease;
}

.mc-meter span.is-mid  { background-color: var(--mark-warn); }
.mc-meter span.is-high { background-color: var(--mark-bad); }

.mc-host-meta {
    margin: 0.1rem 0 0;
    font-size: 0.66rem;
    font-style: italic;
    color: var(--ink-muted);
}

/* ==========================================================================
   6. RESPONSIVE
   ========================================================================== */
@media (max-width: 768px) {
    body { font-size: 16px; }

    nav {
        padding: 0.85rem 1.25rem;
        flex-wrap: wrap;
        gap: 0.5rem 1rem;
    }

    main {
        padding: 2.5rem 1.25rem 3.5rem;
    }

    h1 {
        font-size: 2rem;
    }

    .mc-basic-stats {
        flex-wrap: wrap;
    }
}

/* ==========================================================================
   7. PRINT — it is still a page underneath, so let it be one
   ========================================================================== */
@media print {
    body { background: #fff; }
    header { position: static; }
    a { color: var(--ink); }
    .project, .rail-panel, .card { box-shadow: none; }
}
