/*
 * main.css — Stylesheet for tcorbettclark.github.io
 *
 * Structure is organised using CSS Cascade Layers (@layer).
 * Layers are declared below from lowest to highest precedence,
 * meaning later layers always override earlier ones regardless
 * of selector specificity.
 *
 * Layer order: reset → tokens → base → typography → code →
 *   blockquotes → tables → definition-lists → footnotes → math →
 *   header-nav → layout → content → page-chrome → toc →
 *   welcome → cv → math-problems → utilities → responsive → print
 *
 * The page-chrome layer also includes the site footer.
 *
 * Cascade Layers are a Baseline Widely Available feature (CSS Cascading
 * and Inheritance Level 5) supported in all modern browsers since
 * early 2022 (Chrome 99, Firefox 97, Safari 15.4).
 */

@layer reset, tokens, base, typography, code, blockquotes, tables,
       definition-lists, footnotes, math, header-nav, layout,
       content, page-chrome, toc, welcome, cv, math-problems,
       utilities, responsive, print;

@layer reset {
    /* ==========================================================================
       @layer reset
       Purpose: Universal box-sizing reset to the border-box model.
       Standard: Widely adopted convention popularised by Paul Irish (2011).
         Ensures padding and border are included in element dimensions,
         matching how CSS box-sizing is most intuitively understood.
       ========================================================================== */
    *,
    *::before,
    *::after {
        box-sizing: border-box;
    }
}
@layer tokens {
    /* ==========================================================================
       @layer tokens
       Purpose: Design tokens as CSS custom properties — the single source of
         truth for colours, spacing, typography, and layout dimensions used
         across all layers.
       Notes: Dark mode overrides are co-located with each token group for
         maintainability. Custom properties cascade through layers via var()
         so layer order does not affect their resolution; the layer is
         primarily for structural documentation.
       Standard: CSS Custom Properties (CSS Variables, Level 1).
       ========================================================================== */
    :root {
        --color-bg: #fafaf8;
        --color-text: #1a1a1a;
        --color-text-muted: #666;
        --color-accent: hsl(45, 85%, 45%);
        --color-accent-subtle: hsl(45, 85%, 93%);
        --color-border: #e0e0d8;
        --color-code-bg: hsl(45, 30%, 96%);
        --color-link: hsl(220, 100%, 45%);
        --color-link-hover: hsl(220, 100%, 35%);

        --color-selection-bg: hsl(45, 85%, 85%);
        --color-selection-text: #1a1a1a;

        --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
        --font-mono: "Fira Code", "SF Mono", "Cascadia Code", ui-monospace, monospace;
        --font-size-base: 1rem;
        --font-size-h1: 1.8rem;
        --font-size-h2: 1.35rem;
        --font-size-h3: 1.15rem;
        --font-size-h4: 1.05rem;
        --font-size-h5: 1rem;
        --font-size-h6: 1rem;
        --line-height: 1.65;
        --max-width: 680px;

        --space-xs: 0.25rem;
        --space-sm: 0.5rem;
        --space-md: 1rem;
        --space-lg: 2rem;
        --space-xl: 3rem;
        --space-2xl: 5rem;

        --scroll-offset: 5rem;

        --border-radius: 8px;
    }

    /* Dark mode overrides.
       Standard: prefers-color-scheme media query (CSS Media Queries Level 5).
       Browsers that don't support it will ignore this block entirely. */
    @media (prefers-color-scheme: dark) {
        :root {
            --color-bg: #1a1a18;
            --color-text: #e0e0d8;
            --color-text-muted: #999;
            --color-accent: hsl(45, 80%, 55%);
            --color-accent-subtle: hsl(45, 25%, 18%);
            --color-border: #333;
            --color-code-bg: hsl(45, 10%, 15%);
            --color-link: hsl(220, 80%, 65%);
            --color-link-hover: hsl(220, 80%, 75%);

            --color-selection-bg: hsl(45, 60%, 30%);
            --color-selection-text: #e0e0d8;
        }
    }
}
@layer base {
    /* ==========================================================================
       @layer base
       Purpose: Root-level element styles and global pseudo-elements that set
         the foundation for all subsequent layers.
       Notes: -webkit-text-size-adjust is a Safari/iOS workaround that
         prevents the browser from inflating font sizes on orientation change.
         Standard: text-size-adjust is specified in CSS Text Size Adjustment.
       ========================================================================== */

    html {
        scroll-behavior: smooth;
        -webkit-text-size-adjust: 100%; /* Safari/iOS workaround: prevents font-size inflation on orientation change */
    }

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

    ::selection {
        background-color: var(--color-selection-bg);
        color: var(--color-selection-text);
    }

}
@layer typography {
    /* ==========================================================================
       @layer typography
       Purpose: Base typographic styles for headings, paragraphs, links, lists,
         horizontal rules, and images. These apply site-wide and can be
         overridden by more specific component layers.
       Standard: CSS Fonts Level 4, CSS Text Level 3.
       ========================================================================== */

    h1, h2, h3, h4, h5, h6 {
        font-weight: 600;
        line-height: 1.3;
        margin-top: var(--space-lg);
        margin-bottom: var(--space-sm);
    }

    h1 { font-size: var(--font-size-h1); }
    h2 { font-size: var(--font-size-h2); }
    h3 { font-size: var(--font-size-h3); }
    h4 { font-size: var(--font-size-h4); }
    h5 { font-size: var(--font-size-h5); }
    h6 { font-size: var(--font-size-h6); }

    p {
        margin-top: 0;
        margin-bottom: var(--space-md);
    }

    a {
        color: var(--color-link);
        text-decoration-thickness: 1px;
        text-underline-offset: 2px;
    }

    a:hover {
        color: var(--color-link-hover);
    }

    ul, ol {
        padding-left: var(--space-lg);
        margin-top: 0;
        margin-bottom: var(--space-md);
    }

    li {
        margin-bottom: var(--space-xs);
    }

    hr {
        border: none;
        border-top: 1px solid var(--color-border);
        margin: var(--space-lg) 0;
    }

    img {
        max-width: 100%;
        height: auto;
    }

}
@layer code {
    /* ==========================================================================
       @layer code
       Purpose: Styles for inline code and preformatted blocks, including
         syntax-highlighted code blocks rendered by render-code.js.
       ========================================================================== */

    code {
        font-family: var(--font-mono);
        font-size: 0.9em;
        padding: 0.15em 0.35em;
        border-radius: var(--border-radius);
        background-color: var(--color-code-bg);
    }

    pre {
        margin: var(--space-md) 0;
        padding: var(--space-md);
        overflow-x: auto;
        border: 1px solid var(--color-border);
        border-radius: var(--border-radius);
        background-color: var(--color-code-bg);
        line-height: 1.5;
    }

    pre code {
        padding: 0;
        border-radius: 0;
        background: none;
        font-size: 0.875rem;
    }
}
@layer blockquotes {
    /* ==========================================================================
       @layer blockquotes
       Purpose: Styles for block-level quotations rendered from Markdown
         blockquote syntax (> prefix).
       ========================================================================== */

    blockquote {
        margin: var(--space-md) 0;
        padding-left: var(--space-md);
        border-left: 3px solid var(--color-accent);
        color: var(--color-text-muted);
    }

    blockquote p:last-child {
        margin-bottom: 0;
    }

}
@layer tables {
    /* ==========================================================================
       @layer tables
       Purpose: Styles for data tables rendered from Markdown pipe tables.
       ========================================================================== */

    table {
        display: block; /* Required for overflow-x: auto on the table itself */
        overflow-x: auto; /* Scroll wide tables individually instead of overflowing the page */
        border-collapse: separate; /* Separate model required since display:block breaks border-collapse:collapse */
        border-spacing: 0; /* Visually identical to border-collapse:collapse with separate model */
        width: 100%;
        margin: var(--space-md) 0;
    }

    th, td {
        padding: var(--space-sm) var(--space-md);
        border: 1px solid var(--color-border);
        text-align: left;
    }

    th {
        font-weight: 600;
        background-color: var(--color-accent-subtle);
        white-space: nowrap; /* Prevent headers wrapping so wide tables trigger horizontal scroll */
    }

}
@layer definition-lists {
    /* ==========================================================================
       @layer definition-lists
       Purpose: Styles for definition lists (<dl>, <dt>, <dd>) used in
         structured content like glossaries or metadata listings.
       ========================================================================== */

    dl {
        margin: var(--space-md) 0;
    }

    dt {
        font-weight: 600;
        margin-top: var(--space-md);
    }

    dd {
        margin-left: var(--space-md);
        margin-bottom: var(--space-sm);
    }

}
@layer footnotes {
    /* ==========================================================================
       @layer footnotes
       Purpose: Styles for footnote markup generated by the
         markdown-it-footnote plugin. The footnotes section is rendered as
         an <ol> inside a <div class="footnotes"> at the bottom of the page,
         with superscript <sup> references inline in the text.
       ========================================================================== */

    .footnotes {
        font-size: 0.9rem;
        color: var(--color-text-muted);
        border-top: 1px solid var(--color-border);
        margin-top: var(--space-xl);
        padding-top: var(--space-md);
    }

    .footnotes hr {
        display: none;
    }

    .footnotes ol {
        padding-left: var(--space-lg);
    }

    sup a.footnote-ref {
        color: var(--color-accent);
        text-decoration: none;
        font-weight: 600;
    }

}
@layer math {
    /* ==========================================================================
       @layer math
       Purpose: Styles for mathematical content rendered by KaTeX
         (render-maths.js). Block-level math is centred and horizontally
         scrollable; inline math inherits the monospace font.
       ========================================================================== */

    .math {
        font-family: var(--font-mono);
    }

    .math.block {
        display: block;
        text-align: center;
        margin: var(--space-md) 0;
        overflow-x: auto;
    }

}
@layer header-nav {
    /* ==========================================================================
       @layer header-nav
       Purpose: Site-wide header, branding, navigation, and mobile hamburger
         menu. The header is sticky with a translucent backdrop-blur effect.
       Notes: -webkit-backdrop-filter is a Safari workaround required for
         Safari versions < 18 (which dropped the prefix). The solid
         background-color declaration before the color-mix() declaration
         serves as a progressive-enhancement fallback for browsers that
         don't support color-mix().
       Standard: backdrop-filter (CSS Backdrop Filter Level 1);
         color-mix() (CSS Color Level 5).
       ========================================================================== */

    .site-header {
        position: sticky;
        top: 0;
        z-index: 100;
        background-color: var(--color-bg);
        background-color: color-mix(in srgb, var(--color-bg) 92%, transparent); /* Progressive enhancement: fallback is the solid background above */
        backdrop-filter: blur(8px);
        -webkit-backdrop-filter: blur(8px); /* Safari workaround: prefix required for Safari < 18 */
    }

    .site-header-inner {
        max-width: 900px;
        margin: 0 auto;
        padding: var(--space-sm) var(--space-md);
        display: flex;
        align-items: center;
        justify-content: space-between;
        flex-wrap: wrap;
        gap: var(--space-sm);
    }

    .site-brand {
        min-width: 0;
    }

    .site-name {
        margin: 0;
        font-size: 1.1rem;
        font-weight: 600;
        line-height: 1.3;
    }

    .site-name a {
        color: var(--color-text);
        text-decoration: none;
    }

    .site-name a:hover {
        color: var(--color-accent);
    }

    .site-tagline {
        margin: 0;
        font-size: 0.8rem;
        color: var(--color-text-muted);
    }

    .site-header-rule {
        border: none;
        border-top: 2px solid var(--color-accent);
        margin: 0;
    }

    /* Hamburger toggle button — visible only on narrow screens.
       See the responsive layer for the @media rule that shows it. */
    .nav-toggle {
        display: none;
        background: none;
        border: none;
        cursor: pointer;
        padding: var(--space-sm);
        z-index: 101;
    }

    .nav-toggle-bar {
        display: block;
        width: 20px;
        height: 2px;
        margin: 4px 0;
        background-color: var(--color-text);
        border-radius: 1px;
        transition: transform 0.2s, opacity 0.2s;
    }

    .site-nav {
        display: flex;
        gap: var(--space-md);
        font-size: 0.85rem;
    }

    .site-nav a {
        color: var(--color-text-muted);
        text-decoration: none;
        white-space: nowrap;
    }

    .site-nav a:hover {
        color: var(--color-accent);
    }

}
@layer layout {
    /* ==========================================================================
       @layer layout
       Purpose: Page-level grid layout that positions the main content area
         alongside a sticky table-of-contents sidebar. On narrow screens the
         sidebar is hidden and the layout collapses to a single column.
       Notes: The .welcome-layout variant is a similar grid but wider, used
         only on the homepage.
       Standard: CSS Grid Layout Level 2.
       ========================================================================== */

    .page-layout {
        display: grid;
        grid-template-columns: 1fr 220px;
        gap: var(--space-xl);
        max-width: 920px;
        margin: 0 auto;
        padding: var(--space-md) var(--space-md) var(--space-2xl);
        align-items: start;
    }

    @media (max-width: 960px) {
        .page-layout {
            grid-template-columns: 1fr;
        }
    }

    .page-main {
        min-width: 0;
    }

}
@layer content {
     /* ==========================================================================
       @layer content
        Purpose: Styles for the primary Markdown-rendered content area.
        Notes: scroll-margin-top on heading IDs ensures that in-page anchor
          links scroll past the sticky header.
        ========================================================================== */

    .content {
        max-width: var(--max-width);
        line-height: var(--line-height);
        overflow-wrap: anywhere; /* Allow long unbreakable strings to wrap at any character */
    }

    .content h2 {
        margin-top: var(--space-xl);
        padding-bottom: var(--space-xs);
        border-bottom: 1px solid var(--color-border);
    }

    /* Headings with an id attribute are linkable anchors.
       scroll-margin-top ensures anchor scrolls clear the sticky header
       and must match the IntersectionObserver rootMargin top offset
       used by the TOC scroll-spy in toc.js. Both read the same
       --scroll-offset token from :root. */
    .content h1[id],
    .content h2[id],
    .content h3[id],
    .content h4[id] {
        scroll-margin-top: var(--scroll-offset);
    }

    /* Table styles e.g. in Markdown */
    .table-sm {
        font-size: 0.85rem;
    }
    .table-sm th,
    .table-sm td {
        padding: var(--space-xs) var(--space-sm);
    }
}
@layer page-chrome {
    /* ==========================================================================
       @layer page-chrome
       Purpose: Supplementary page elements that frame the main content —
         site footer, breadcrumbs, page titles, and draft-status banners.
       ========================================================================== */

    /* Footer */
    .site-footer {
        max-width: 800px;
        margin: 0 auto;
        padding: var(--space-lg) var(--space-md);
        font-size: 0.85rem;
        color: var(--color-text-muted);
        text-align: center;
    }

    .site-footer p {
        margin-bottom: var(--space-xs);
    }

    .breadcrumb {
        margin: 0 0 var(--space-sm);
        font-size: 0.85rem;
        color: var(--color-text-muted);
    }

    .breadcrumb a {
        color: var(--color-text-muted);
    }

    .breadcrumb a:hover {
        color: var(--color-accent);
    }

    .breadcrumb-sep {
        margin: 0 var(--space-xs);
        opacity: 0.5;
    }

    .page-title {
        font-size: 1.5rem;
        font-weight: 400;
        margin-top: 0;
        margin-bottom: var(--space-lg);
        padding-bottom: var(--space-sm);
        border-bottom: 2px solid var(--color-accent);
    }

    .draft-banner {
        margin-bottom: var(--space-md);
        padding: var(--space-sm) var(--space-md);
        border-left: 3px solid var(--color-accent);
        background-color: var(--color-accent-subtle);
        font-size: 0.85rem;
    }

    .draft-banner a {
        color: var(--color-text);
        font-weight: 600;
    }

    /* Background watermark for draft pages, referencing an SVG file. */
    .draft-watermark {
        background-image: url("draft-watermark.svg");
    }

}
@layer toc {
    /* ==========================================================================
       @layer toc
       Purpose: Table of contents sidebar — a sticky, hierarchical outline
         shown alongside the main content on wide screens. Hidden entirely
         on screens narrower than 960px (see layout layer).
       Standard: CSS Position Sticky.
       ========================================================================== */

    .page-toc {
        position: sticky;
        top: 5rem;
        font-size: 0.85rem;
        line-height: 1.4;
    }

    @media (max-width: 960px) {
        .page-toc {
            display: none;
        }
    }

    .toc-title {
        font-weight: 600;
        font-variant: small-caps;
        margin: 0 0 var(--space-sm);
        padding-bottom: var(--space-xs);
        border-bottom: 1px solid var(--color-border);
        color: var(--color-text-muted);
    }

    .toc-list {
        list-style: none;
        padding: 0;
        margin: 0;
    }

    .toc-list li {
        margin-bottom: var(--space-xs);
    }

    .toc-h2 {
        padding-left: 0;
    }

    .toc-h3 {
        padding-left: var(--space-md);
        font-size: 0.8rem;
    }

    .toc-sublist {
        list-style: none;
        padding: 0;
        margin: var(--space-xs) 0 0;
    }

    .toc-sublist li {
        margin-bottom: var(--space-xs);
    }

    .toc-list a {
        color: var(--color-text-muted);
        text-decoration: none;
    }

    .toc-list a:hover {
        color: var(--color-accent);
    }

    .toc-active > a {
        color: var(--color-accent);
        text-decoration: underline;
        text-underline-offset: 3px;
        text-decoration-thickness: 2px;
    }

    /* On touch devices, tapping a TOC link focuses it. When the scroll spy
       later moves .toc-active to a different heading, the previously-tapped
       link loses .toc-active (so the underline vanishes) but retains :focus,
       leaving a lone yellow heading. Override :focus to match the default
       style so it doesn't linger. */
    .toc-list a:focus {
        color: var(--color-text-muted);
        outline: none;
    }

    /* Re-apply the accent colour when the focused link is also active. */
    .toc-active > a:focus {
        color: var(--color-accent);
    }

}
@layer welcome {
    /* ==========================================================================
       @layer welcome
       Purpose: Homepage-specific layout and components: the two-column welcome
         grid, profile card, pursuits list, and social links.
       Notes: The welcome sidebar uses position:sticky below the header.
         On narrow screens the layout collapses to a single column and the
         profile card image is constrained to 150px.
       ========================================================================== */

    .welcome-layout {
        display: grid;
        grid-template-columns: 1fr 260px;
        gap: var(--space-xl);
        max-width: 900px;
        margin: 0 auto;
        padding: var(--space-md) var(--space-md) var(--space-2xl);
        align-items: start;
    }

    @media (max-width: 768px) {
        .welcome-layout {
            grid-template-columns: 1fr;
        }
    }

    .welcome-content {
        min-width: 0;
    }

    .welcome-sidebar {
        position: sticky;
        top: 5rem;
    }

    .profile-card {
        text-align: center;
    }

    .profile-card img {
        width: 100%;
        max-width: 200px;
        border-radius: var(--border-radius);
    }

    @media (max-width: 768px) {
        .profile-card img {
            max-width: unset;
            width: 150px;
        }
    }

    .profile-heading {
        font-size: 1rem;
        font-weight: 600;
        font-variant: small-caps;
        margin: var(--space-lg) 0 var(--space-sm);
        padding-bottom: var(--space-xs);
        border-bottom: 1px solid var(--color-border);
    }

    .pursuits-list {
        list-style: none;
        padding: 0;
        text-align: left;
    }

    .pursuits-list li {
        margin-bottom: var(--space-xs);
    }

    .pursuits-list li i {
        width: 1.5em;
        text-align: center;
        color: var(--color-accent);
    }

    .social-links {
        display: flex;
        justify-content: center;
    }

    .social-link {
        color: var(--color-text-muted);
        font-size: 1.2rem;
        text-decoration: none;
        padding: var(--space-xs);
    }

    .social-link:hover {
        color: var(--color-accent);
    }

}
@layer cv {
    /* ==========================================================================
       @layer cv
       Purpose: Curriculum vitae / résumé page styles — section headings,
         item layout, and meta information (title, company, dates).
       ========================================================================== */

    .cv-section {
        margin: var(--space-xl) 0;
    }

    .cv-section h2 {
        font-size: 1.1rem;
        font-weight: 600;
        font-variant: small-caps;
        margin-bottom: var(--space-md);
        padding-bottom: var(--space-xs);
        border-bottom: 1px solid var(--color-border);
    }

    .cv-item {
        margin-bottom: var(--space-md);
    }

    .cv-meta {
        display: flex;
        justify-content: space-between;
        align-items: baseline;
        flex-wrap: wrap;
        gap: var(--space-sm);
    }

    .cv-title {
        font-weight: 600;
    }

    .cv-time {
        font-size: 0.85rem;
        color: var(--color-text-muted);
    }

    .cv-company {
        font-size: 0.9rem;
        color: var(--color-text-muted);
    }

    .cv-details {
        margin-top: var(--space-xs);
    }

    .cv-intro {
        margin-bottom: var(--space-md);
    }

}
@layer math-problems {
    /* ==========================================================================
       @layer math-problems
       Purpose: Styles specific to the maths problems section — currently just
         a small-image class for constraining diagram widths.
       ========================================================================== */

    .small-image {
        width: 200px;
    }

}
@layer utilities {
    /* ==========================================================================
       @layer utilities
       Purpose: Small single-purpose utility classes that should override all
         component styles. Kept in their own high-precedence layer.
       ========================================================================== */

    .smallcaps {
        font-variant: small-caps;
    }

}
@layer responsive {
    /* ==========================================================================
       @layer responsive
       Purpose: Responsive overrides that must win over component layers.
         Two breakpoints:
         - ≤768px: mobile navigation (hamburger toggle, collapsed nav).
         - ≤480px: small-screen type scaling for the narrowest devices.
       Notes: Layout and TOC breakpoints (≤960px) and the welcome sidebar
         breakpoint (≤768px) are co-located with their respective components
         in the layout, toc, and welcome layers. Those are lower-precedence
         layers but still work correctly because the selectors only target
         their own components.
       Standard: CSS Media Queries Level 4.
       ========================================================================== */

    /* Mobile navigation — hamburger toggle and collapsed nav.
       At ≤768px the horizontal nav is hidden and a toggle button appears.
       The .site-nav-open class is toggled by nav-toggle.js. */
    @media (max-width: 768px) {
        .nav-toggle {
            display: block;
        }

        .site-nav {
            display: none;
            flex-direction: column;
            width: 100%;
            gap: 0;
            padding: var(--space-sm) 0;
            border-top: 1px solid var(--color-border);
        }

        .site-nav-open {
            display: flex;
        }

        .site-nav a {
            padding: var(--space-sm) 0;
        }
    }

    /* Small-screen type scaling for the narrowest devices. */
    @media (max-width: 480px) {
        :root {
            --font-size-h1: 1.5rem;
            --font-size-h2: 1.2rem;
            --font-size-h3: 1.05rem;
            --font-size-h4: 1rem;
        }

        .page-title { font-size: 1.3rem; }

        body {
            font-size: 0.95rem;
        }
    }

}
@layer print {
    /* ==========================================================================
       @layer print
       Purpose: Print stylesheet that hides navigation, sidebars, and
         interactive elements; simplifies colours to black on white; and
         prevents code blocks from being split across page breaks.
       Notes: This is the highest-precedence layer, ensuring print rules
         always override screen styles.
       Standard: CSS Paged Media Level 3.
       ========================================================================== */

    @media print {
        body {
            color: #000;
            background: #fff;
        }

        .site-header,
        .site-footer,
        .breadcrumb,
        .draft-banner,
        .page-toc,
        .nav-toggle {
            display: none;
        }

        .page-main,
        .welcome-layout,
        .page-layout {
            max-width: 100%;
            padding: 0;
        }

        .page-layout {
            display: block;
        }

        a {
            color: #000;
            text-decoration: underline;
        }

        pre {
            border: 1px solid #ccc;
            page-break-inside: avoid;
        }
    }

}
