/* ── Page shell ────────────────────────────────────────────────
   Global chrome shared by every surface - Personal Website,
   Website Studio, Build2Teach Studio, Central Portal: reset, base
   typography mapping, header/nav/footer, and the small set of
   page-level primitives (hero, muted section, back-links) that
   aren't specific to reading or Studio density. Reading-mode
   long-form content lives in article.css; Studio-only chrome
   lives in studio.css.
*/

/* ── Reset ─────────────────────────────────────────────────── */
*, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }
}

body {
    font-family: var(--font-sans);
    font-size: var(--type-body-size);
    font-weight: var(--type-body-weight);
    line-height: var(--type-body-line-height);
    color: var(--color-text);
    background: var(--color-background);
}

img, svg {
    max-width: 100%;
    display: block;
}

ul, ol {
    list-style: none;
}

/* ── Headings - the named scale mapped onto elements ─────────── */
h1, h2, h3, h4 {
    font-weight: var(--type-heading-l-weight);
    color: var(--color-heading);
}

h1 {
    font-size: var(--type-heading-xl-size);
    font-weight: var(--type-heading-xl-weight);
    line-height: var(--type-heading-xl-line-height);
    letter-spacing: var(--type-heading-xl-letter-spacing);
}

h2 {
    font-size: var(--type-heading-l-size);
    line-height: var(--type-heading-l-line-height);
    margin-bottom: var(--space-4);
}

h3 {
    font-size: var(--type-heading-m-size);
    line-height: var(--type-heading-m-line-height);
}

h4 {
    font-size: var(--type-heading-s-size);
    line-height: var(--type-heading-s-line-height);
}

h5, h6 {
    font-weight: var(--type-heading-xs-weight);
    color: var(--color-heading);
}

h5 {
    font-size: var(--type-heading-xs-size);
    line-height: var(--type-heading-xs-line-height);
}

h6 {
    font-size: var(--type-heading-2xs-size);
    line-height: var(--type-heading-2xs-line-height);
    letter-spacing: var(--type-heading-2xs-letter-spacing);
}

/* ── Paragraphs & body copy ───────────────────────────────────── */
p {
    color: var(--color-text);
}

p + p {
    margin-top: var(--space-3);
}

/* ── Links ───────────────────────────────────────────────────
   Interactive color is a signal, not a default: an ordinary link
   takes the color of its surrounding text (a heading link reads as a
   heading, a body link reads as body copy) and only shifts to
   --color-interactive on hover/focus. --color-interactive is aliased
   to Brand red (--color-primary) - blue retired as an interactive
   color sitewide - but the *role* stays distinct from a CTA: hover/
   focus still means "you're here," not "act now," it just happens to
   render in the same red now that both roles point at the same
   token. See components/buttons.css and README's "Brand colors" for
   the CTA-weight rule this is distinct from. Components that need a
   permanent color (nav's .is-active, .btn-primary, badges, content-
   family accents) set their own color and win on specificity
   regardless of this base rule. */
a {
    color: inherit;
    text-decoration: none;
    transition: color var(--transition-fast);
}

a:hover {
    color: var(--color-interactive);
    text-decoration: underline;
}

/* ── Keyboard focus - visible everywhere by default ──────────
   Components may add their own focus treatment, but nothing in
   this system ever removes focus outlines outright. Same Interactive
   token as hover (now Brand red, not blue) - a focus ring means
   "you're here," the same role as hover, not "act now". */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
    outline: 2px solid var(--color-interactive);
    outline-offset: 2px;
}

/* ── Page container ─────────────────────────────────────────
   Full desktop canvas (Issue 33): the shell itself uses the wide
   --container-canvas tier by default - composition width, not text
   width. A page whose content shouldn't inherit that extra width
   (a form, a small fixed card index) opts back down explicitly with
   .container-content below, rather than every page opting in. */
.site-header,
.main-content {
    max-width: var(--container-canvas);
    margin: 0 auto;
    padding: 0 var(--space-5);
}

/* Opt-out to the pre-33 content width - forms (inputs are full-width
   and become unusably wide on the full canvas) and small fixed card
   indexes that don't benefit from more columns. Long-form detail
   pages don't need this: they already self-cap via .reading, so the
   extra canvas becomes deliberate whitespace next to their sidebar,
   not a width regression. */
.container-content {
    max-width: var(--container-max);
    margin: 0 auto;
}

/* ── Development environment notice ───────────────────────────
   Slim status bar above .site-header (templates/base.html), rendered
   only when SHOW_DEVELOPMENT_NOTICE is on for the current environment
   (config.settings.base, exposed via apps/core/context_processors.py's
   development_notice) - the dev/test deployment, never a real
   production launch. No new color introduced: the surface is
   --color-surface-muted/--color-border, the system's ordinary
   secondary-panel neutral, not a bespoke warm tone (this used to
   borrow --code-surface/--code-border's light sand as a second,
   unrelated warm-neutral surface, back when that family meant a light
   editor panel - Issue 60 repointed --code-surface/-border to a dark
   technical surface, so this bar needed its own light-neutral pair
   rather than silently going dark); the text is the primary dark-grey
   (--color-heading); the leading dot is Brand red (--color-primary)
   used as a small "live" indicator dot, not a full-banner treatment -
   the whole bar deliberately stays a calm, quiet neutral so this
   doesn't read as an alert. Stays in normal document flow (not
   sticky/fixed) so it simply scrolls away ahead of .site-header's own
   sticky top:0 - never overlapping it. */
.dev-notice {
    margin: 0;
    background: var(--color-surface-muted);
    border-bottom: 1px solid var(--color-border);
    color: var(--color-heading);
    text-align: center;
    padding: var(--space-2) var(--space-4);
    font-size: var(--type-small-size);
}

.dev-notice__dot {
    display: inline-block;
    width: 0.4em;
    height: 0.4em;
    margin-right: 0.5em;
    border-radius: 50%;
    background: var(--color-primary);
    vertical-align: middle;
}

/* ── Header / navigation ───────────────────────────────────── */
.site-header {
    position: sticky;
    top: 0;
    z-index: var(--z-sticky-header, 100);
    background: var(--color-background);
    padding-top: var(--space-5);
    padding-bottom: var(--space-5);
    border-bottom: 1px solid var(--color-border);
}

.nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    flex-wrap: wrap;
    gap: var(--space-3);
}

.nav-identity {
    display: flex;
    flex-direction: column;
}

.nav-brand {
    font-weight: var(--type-heading-l-weight);
    font-size: 1.1rem;
    color: var(--color-heading);
}

.nav-brand:hover {
    color: var(--color-interactive);
    text-decoration: none;
}

.nav-descriptor {
    color: var(--color-text-muted);
    font-size: var(--type-small-size);
}

/* Mobile menu toggle - hidden on desktop, a plain CSS-drawn hamburger
   below the .nav breakpoint. No icon font/SVG dependency. */
.nav-toggle {
    display: none;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    width: 2rem;
    height: 2rem;
    padding: 0;
    background: none;
    border: none;
    cursor: pointer;
}

.nav-toggle-bar {
    display: block;
    width: 100%;
    height: 2px;
    background: var(--color-heading);
}

.nav-links {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-5);
}

.nav-links a {
    color: var(--color-text-muted);
    font-size: var(--type-small-size);
    font-weight: var(--type-label-weight);
    padding: var(--space-1) 0;
    border-bottom: 2px solid transparent;
}

.nav-links a:hover {
    color: var(--color-interactive);
    text-decoration: none;
}

/* Issue 45 v2 (approved mockup): "active navigation indicated with
   red," uniformly - not each tab's own content-family accent (Issue
   45's prior composition revision, which colored the Projects tab
   blue, Articles green, Work With Me orange/red while it was active).
   The mockup's Studio nav states this generally too ("current section:
   red indicator"), so both navs now use one consistent "you are here"
   signal, distinct from the content-family accents used elsewhere
   (cards, icons) - simpler, and it matches Red's role as the one
   attention color in this system. */
.nav-links a.is-active {
    color: var(--color-primary);
    border-bottom-color: var(--color-primary);
}

/* "Work With Me" - restrained emphasis, not a filled button. Weight is
   the only permanent distinguisher; color is reserved for :hover/.is-active
   so this link doesn't read as "active" on every unrelated page. */
.nav-links a.nav-emphasis {
    font-weight: var(--type-heading-s-weight);
}

/* ── Local sub-navigation ──────────────────────────────────────
   A secondary nav beneath the main site nav, for a section with its
   own child pages (e.g. About). Same visual language as .nav-links -
   muted links, active one picked out with color + underline - just a
   distinct class so it can sit under a heading without inheriting
   .nav's space-between/flex-wrap layout rules. ────────────────────── */
.subnav {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-5);
    margin-bottom: var(--space-6);
    padding-bottom: var(--space-3);
    border-bottom: 1px solid var(--color-border);
}

.subnav a {
    color: var(--color-text-muted);
    font-size: var(--type-small-size);
    font-weight: var(--type-label-weight);
    padding: var(--space-1) 0;
    border-bottom: 2px solid transparent;
}

.subnav a:hover {
    color: var(--color-interactive);
    text-decoration: none;
}

.subnav a.is-active {
    color: var(--color-primary);
    border-bottom-color: var(--color-primary);
}

/* ── Main content ──────────────────────────────────────────── */
.main-content {
    padding-top: var(--space-8);
    padding-bottom: var(--space-10);
    min-height: 60vh;
}

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

/* One-line framing under a section heading (e.g. Home's Projects/
   Articles/Work With Me) - explains what the section is for without
   another heading level or a color change. */
.section-lede {
    color: var(--color-text-muted);
    margin-bottom: var(--space-4);
}

.section-narrow {
    max-width: var(--container-narrow);
}

/* ── Auth panel (Website Studio sign-in) ──────────────────────────
   A single small card, not a bespoke split-screen login layout -
   reuses components/cards.css's .card (white surface, hairline
   border, shadow-card) for the same "distinct object on the canvas"
   signal every other card already carries, centered and capped to a
   compact width since it holds one short task, not reading content. */
.auth-section {
    display: flex;
    justify-content: center;
}

/* Plain .card, no added accent edge - white + dark grey + Brand red
   is this panel's entire palette; the button alone carries the red,
   the same way every other card on the site carries no border color
   of its own (see cards.css's own note on this). */
.auth-panel {
    width: 100%;
    max-width: 500px;
}

/* Static, not another hover-elevating card - nothing on this panel is
   a link/list item, so it shouldn't lift as the pointer crosses it
   while someone types. */
.auth-panel:hover {
    box-shadow: var(--shadow-card);
}

.auth-panel .eyebrow {
    margin-bottom: var(--space-1);
}

/* White fields, not --color-surface-muted's sitewide grey - grey read
   as "disabled/default form," which this panel moves away from even
   though the card itself stays white too now. */
.auth-panel input[type="text"],
.auth-panel input[type="password"] {
    background: var(--color-background);
}

/* components/forms.css's global autofill fix pins the inset fill to
   --color-surface-muted (this system's usual grey field) - overridden
   here to white so a browser-autofilled username still matches this
   panel's white fields instead of reverting to grey. */
.auth-panel input:-webkit-autofill,
.auth-panel input:-webkit-autofill:hover,
.auth-panel input:-webkit-autofill:focus {
    -webkit-box-shadow: 0 0 0 1000px var(--color-background) inset;
}

.auth-panel h1 {
    margin-bottom: var(--space-2);
}

.auth-panel form {
    margin-top: var(--space-5);
}

.auth-submit {
    width: 100%;
    text-align: center;
}

/* Alternate / muted section wrapper - for visual rhythm breaks
   (e.g. Home page sections), not the default page background. */
.section--muted {
    background: var(--color-surface-muted);
    border-radius: var(--radius-lg);
    padding: var(--space-6) var(--space-5);
}

/* Commercial section wrapper (Issue 45, v1 stabilization pass). A
   full warm orange/sand gradient behind this section was tried and
   reverted - combined with the CTA, the hero, and this same family's
   card/border accents, it made orange read as the page's dominant
   identity again, the exact problem Issue 45 exists to fix. A very
   subtle neutral (the same --color-surface-muted every other muted
   section on the site already uses) still marks Work With Me as its
   own visual rhythm break from Projects/Articles above it; the
   section's commercial identity now comes from its cards' accent
   borders alone (components/cards.css's .service-item), a small,
   controlled marker rather than a large colored field. */
.section--commercial {
    background: var(--color-surface-muted);
    border-radius: var(--radius-lg);
    padding: var(--space-6) var(--space-5);
}

/* ── Footer - the page's dark anchor (Issue 45 composition revision) ──
   A full-bleed --palette-dark-grey field, not a continuation of the
   white canvas above it: the footer terminates the page composition
   and gives the stable dark neutral a real large-scale presence, not
   just a text color. Full-bleed without a new wrapper element - the
   max-width/centering/padding that used to live on .site-footer
   itself (shared with .site-header/.main-content) moved onto
   .footer-groups/.footer-bottom instead, so .site-footer's own box
   (and its background) spans the full viewport while its content
   still lines up with the header/main canvas above it. See
   tokens/colors.css's "Footer (dark anchor)" block for why every
   color below is a dedicated --color-footer-* token rather than the
   light-surface tokens used everywhere else on the page - a dark
   background needs its own foreground set, not --color-text-muted/
   --color-interactive reused past their tested contrast range. */
.site-footer {
    background: var(--color-footer-bg);
    padding-top: var(--space-8);
    padding-bottom: var(--space-6);
    color: var(--color-footer-text-muted);
    font-size: var(--type-small-size);
}

.footer-groups {
    max-width: var(--container-canvas);
    margin: 0 auto var(--space-6);
    padding: 0 var(--space-5);
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--space-6);
    text-align: left;
}

.footer-group h2 {
    font-size: var(--type-small-size);
    font-weight: var(--type-label-weight);
    color: var(--color-footer-text);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-bottom: var(--space-3);
}

.footer-group ul {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

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

.footer-group a:hover {
    color: var(--color-footer-link-hover);
    text-decoration: none;
}

/* Elsewhere links (GitLab/LinkedIn/GitHub) - same {% icon %} tag
   Website Studio uses for Technologies/Media, just sized down to sit
   quietly beside small footer text rather than at the 20px UI-chrome
   size. Color still comes from the link itself via currentColor, so
   hover recolors icon and label together with no extra rule. */
.footer-link-icon {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}

.footer-link-icon .icon {
    width: 16px;
    height: 16px;
}

.footer-identity-name {
    color: var(--color-footer-text);
    font-weight: var(--type-heading-l-weight);
}

.footer-bottom {
    max-width: var(--container-canvas);
    margin: 0 auto;
    padding: 0 var(--space-5);
    border-top: 1px solid var(--color-footer-border);
    padding-top: var(--space-4);
    text-align: center;
    /* the global `p` rule sets --color-text, which would otherwise beat
       .site-footer's inherited --color-footer-text-muted here */
    color: var(--color-footer-text-muted);
}

/* ── Hero - a page's single largest mark (home page). ─────────
   A single asymmetric column, not a two-column grid: .hero-content
   caps its own width well short of the container, so the headline
   reads with a confident, deliberate measure and the remaining
   desktop width is intentional negative space rather than a second
   column filled with a redundant restatement of the tagline. Scales
   down to full width naturally below that cap - no separate mobile
   breakpoint needed. */
.hero {
    padding: var(--space-8) 0;
}

/* Issue 45 explored a decorative geometric field in the hero's open
   right-hand canvas (a layered pseudo-element background) across
   several revisions; it was removed for v1.0 - the space is left
   intentionally clean, reserved for a planned introductory video, not
   filled with another color composition. See the decision doc's
   final section for the removal rationale. */
.hero-content {
    max-width: 44rem;
}

/* Identity block - the eyebrow name plus role descriptor, set off
   from the headline by a rule so it reads as a running head rather
   than part of the headline's own hierarchy. */
.hero-mark {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-2) var(--space-4);
    padding-bottom: var(--space-4);
    margin-bottom: var(--space-6);
    border-bottom: 1px solid var(--color-border);
}

.hero-eyebrow {
    font-family: var(--font-mono);
    font-size: var(--type-small-size);
    font-weight: var(--type-label-weight);
    color: var(--color-heading);
}

.hero-descriptor {
    font-size: var(--type-small-size);
    color: var(--color-text-muted);
}

.hero h1 {
    font-size: var(--type-display-size);
    font-weight: var(--type-display-weight);
    line-height: var(--type-display-line-height);
    letter-spacing: var(--type-display-letter-spacing);
    margin-bottom: var(--space-4);
}

.hero-lede {
    font-size: var(--type-body-lg-size);
    line-height: var(--type-body-lg-line-height);
    color: var(--color-text-muted);
    max-width: 46ch;
    margin-bottom: var(--space-6);
}

.hero-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
}

/* ── Links / navigation helpers ────────────────────────────── */
.link-more {
    font-size: var(--type-small-size);
    font-weight: var(--type-label-weight);
}

.link-back {
    display: inline-block;
    margin-top: var(--space-6);
    color: var(--color-text-muted);
    font-size: var(--type-small-size);
}

/* ── Utilities - small, reusable, and justified only; not a
   general-purpose utility framework. Add sparingly. ──────────── */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

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

/* ── Responsive ────────────────────────────────────────────── */
@media (max-width: 640px) {
    .nav-descriptor {
        display: none;
    }

    .nav-toggle {
        display: flex;
    }

    /* Collapsed by default; the toggle button reveals it as a full-width
       stacked panel (site-header.js toggles .is-open + aria-expanded). */
    .nav-links {
        display: none;
        flex-direction: column;
        gap: var(--space-4);
        width: 100%;
        margin-top: var(--space-4);
    }

    .nav-links.is-open {
        display: flex;
    }

    body.nav-open {
        overflow: hidden;
    }

    .main-content {
        padding-top: var(--space-6);
        padding-bottom: var(--space-8);
    }

    .footer-groups {
        grid-template-columns: 1fr;
        gap: var(--space-5);
    }
}
