/* ═══════════════════════════════════════════════════════════════════════════
   BAYA PLATFORM — design tokens and shell
   ═══════════════════════════════════════════════════════════════════════════

   This is the PLATFORM identity: home, authentication, account, global chrome.
   It is deliberately NOT Module 1's identity.

   The approved direction (client sign-off, Aug 2026) is editorial, botanical
   and scientific: warm parchment, deep botanical green, sage, desaturated teal,
   warm amber, restrained terracotta. It should read as an elegant chemistry
   education brand, not as a SaaS dashboard.

   COLOUR ON THE PLATFORM BELONGS TO THE MODULES
   The shell stays calm — green, parchment, ink. Each module card carries its
   own accent, so the page states the architecture it implements: one platform
   holding four worlds. Modules are NOT flattened into one green theme.

   ISOLATION RULE
   These variables are namespaced `--pf-*`. Module 1's tokens.css uses bare
   names (--ink, --gold, --paper). The two files are never loaded on the same
   page, and the prefix means that even if that ever happened by accident,
   neither could overwrite the other.

   NEVER load shared/styles/tokens.css on a platform page.
   NEVER load this file inside a module.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* ── The approved palette, as named brand colours. ──
     Kept separate from the semantic tokens below so a designer can find the
     brand green, and a component can ask for "the page background" without
     needing to know which brand colour that happens to be today. */
  --pf-green:      #1F3D2E;   /* deep botanical — primary brand            */
  --pf-green-2:    #2C5340;   /* raised green, for hover on dark surfaces  */
  --pf-sage:       #6B8F71;   /* secondary structure                       */
  --pf-teal:       #4C7A7B;   /* analytical / scientific accents           */
  --pf-terracotta: #C76D4A;   /* module 4, warm accent states              */
  --pf-amber:      #E2B252;   /* highlights, selected states               */
  --pf-ivory:      #F2E9D8;   /* warm ivory                                */
  --pf-charcoal:   #2B2B2B;   /* primary text                              */

  /* ── Semantic. These names are load-bearing: portal.css and every auth,
        account and error template already speak them. ── */
  --pf-ink:        var(--pf-charcoal);
  --pf-ink-2:      #4A4A44;
  /* Darkened from #6E6A61, which measured 4.37:1 on the parchment ground — under
     the 4.5:1 AA floor. It carries the kicker labels, the topic tags and the
     value strip, all at 11–12px, so none of that is "large text" and none of it
     got a pass. */
  --pf-ink-3:      #5E5A52;
  --pf-ink-4:      #97918655;   /* hairline / disabled — alpha on purpose */

  --pf-ground:     #F0E6DA;     /* warm parchment - matches the exports   */
  --pf-surface:    #FDFAF4;     /* card / panel                           */
  --pf-surface-2:  #EDE4D2;     /* recessed band                          */
  --pf-line:       rgba(31, 61, 46, 0.16);
  --pf-line-2:     rgba(31, 61, 46, 0.08);

  /* The one platform signal colour is the brand green: focus rings, the
     primary action, the active nav item. */
  --pf-signal:      var(--pf-green);
  --pf-signal-ink:  #F7F3E9;
  --pf-signal-soft: rgba(31, 61, 46, 0.08);

  /* Semantic states, kept in the palette's own register rather than borrowed
     from a generic red/green/amber set. */
  --pf-ok:          #2F6B4A;
  --pf-warn:        #9A6B1F;
  --pf-danger:      #A8452C;
  --pf-danger-soft: rgba(168, 69, 44, 0.09);

  /* Restrained elevation. The reference uses thin borders and almost no
     shadow — the depth comes from the paper, not from a drop shadow. */
  --pf-shadow:     0 1px 2px rgba(43, 43, 43, .04), 0 6px 18px rgba(31, 61, 46, .05);
  --pf-shadow-lg:  0 2px 6px rgba(43, 43, 43, .05), 0 20px 46px rgba(31, 61, 46, .10);

  /* ── Type ──
     Playfair Display for editorial display, Source Sans 3 for everything a
     person actually operates. The contrast between the two IS the typography:
     an editorial title over a clean modern interface. Playfair is never used
     for UI, and Source Sans 3 covers Arabic. */
  --pf-serif: 'Playfair Display', Georgia, 'Times New Roman', serif;
  --pf-sans:  'Source Sans 3', ui-sans-serif, system-ui, -apple-system,
              'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  --pf-mono:  ui-monospace, 'Cascadia Mono', 'Segoe UI Mono', 'SF Mono', Menlo, monospace;

  --pf-fs-xs:   0.75rem;
  --pf-fs-sm:   0.875rem;
  --pf-fs-base: 1rem;
  --pf-fs-md:   1.0625rem;
  --pf-fs-lg:   clamp(1.25rem, 1.1rem + 0.5vw, 1.5rem);
  --pf-fs-xl:   clamp(1.6rem, 1.3rem + 1.4vw, 2.35rem);
  --pf-fs-2xl:  clamp(2.1rem, 1.5rem + 2.6vw, 3.4rem);
  --pf-fs-3xl:  clamp(2.6rem, 1.6rem + 4vw, 4.6rem);

  /* ── Space ── */
  --pf-space-1: 4px;
  --pf-space-2: 8px;
  --pf-space-3: 14px;
  --pf-space-4: 22px;
  --pf-space-5: 34px;
  --pf-space-6: 52px;
  --pf-space-7: 76px;
  --pf-space-8: 108px;

  /* Controlled radius. Nothing here is a pill and nothing is a giant card. */
  --pf-radius:    10px;
  --pf-radius-sm: 6px;
  --pf-radius-lg: 14px;

  --pf-ease:  cubic-bezier(0.16, 1, 0.3, 1);
  --pf-t-fast: .16s var(--pf-ease);
  --pf-t:      .24s var(--pf-ease);

  /* ── Module accents ──
     Taken from the approved module identity swatches. Each module owns two:
     a lead colour and a highlight. The shell never uses them. */
  --pf-m1:       #1F3D2E;  --pf-m1-hi: #E2B252;
  --pf-m2:       #4C7A7B;  --pf-m2-hi: #7FBDB1;
  --pf-m3:       #6B8F71;  --pf-m3-hi: #A3B18A;
  --pf-m4:       #C76D4A;  --pf-m4-hi: #E49A6A;

  color-scheme: light;
}

/* ═══ NIGHT ═══
   The same platform at night, not a different design. The composition, the
   typography, the hierarchy and every module identity survive; only the
   environment changes. Deliberately art-directed rather than inverted:
   parchment becomes deep forest, ink becomes warm ivory, and the accents are
   raised just enough to hold contrast without turning neon. */
@media (prefers-color-scheme: dark) {
  :root:not([data-pf-theme="light"]) {
    --pf-green:      #7FA886;
    --pf-green-2:    #9BC2A1;
    --pf-sage:       #8FAE95;
    --pf-teal:       #6FA3A4;
    --pf-terracotta: #D98A66;
    --pf-amber:      #EFC97E;
    --pf-ivory:      #F2E9D8;

    --pf-ink:        #F2E9D8;
    --pf-ink-2:      #D8C9A8;
    --pf-ink-3:      #B3C4B6;
    --pf-ink-4:      #7C8C8055;

    --pf-ground:     #081711;
    --pf-surface:    #102A1F;
    --pf-surface-2:  #16332A;
    --pf-line:       rgba(242, 233, 216, 0.14);
    --pf-line-2:     rgba(242, 233, 216, 0.07);

    --pf-signal:      #8FAE95;
    --pf-signal-ink:  #0B1713;
    --pf-signal-soft: rgba(143, 174, 149, 0.14);

    --pf-ok:          #7FC79B;
    --pf-warn:        #E2B252;
    --pf-danger:      #E4917F;
    --pf-danger-soft: rgba(228, 145, 127, 0.14);

    --pf-shadow:     0 1px 2px rgba(0, 0, 0, .45), 0 6px 18px rgba(0, 0, 0, .35);
    --pf-shadow-lg:  0 2px 6px rgba(0, 0, 0, .5), 0 20px 46px rgba(0, 0, 0, .55);

    --pf-m1: #3E7355;  --pf-m1-hi: #E2B252;
    --pf-m2: #3F7A7C;  --pf-m2-hi: #86C6BC;
    --pf-m3: #5C8663;  --pf-m3-hi: #AFC298;
    --pf-m4: #B75F3E;  --pf-m4-hi: #E9A877;

    color-scheme: dark;
  }
}

/* The explicit choice, which must win in both directions. */
:root[data-pf-theme="dark"] {
  --pf-green:      #7FA886;
  --pf-green-2:    #9BC2A1;
  --pf-sage:       #8FAE95;
  --pf-teal:       #6FA3A4;
  --pf-terracotta: #D98A66;
  --pf-amber:      #EFC97E;
  --pf-ivory:      #F2E9D8;

  --pf-ink:        #F2E9D8;
  --pf-ink-2:      #D8C9A8;
  --pf-ink-3:      #B3C4B6;
  --pf-ink-4:      #7C8C8055;

  --pf-ground:     #081711;
  --pf-surface:    #102A1F;
  --pf-surface-2:  #16332A;
  --pf-line:       rgba(242, 233, 216, 0.14);
  --pf-line-2:     rgba(242, 233, 216, 0.07);

  --pf-signal:      #8FAE95;
  --pf-signal-ink:  #0B1713;
  --pf-signal-soft: rgba(143, 174, 149, 0.14);

  --pf-ok:          #7FC79B;
  --pf-warn:        #E2B252;
  --pf-danger:      #E4917F;
  --pf-danger-soft: rgba(228, 145, 127, 0.14);

  --pf-shadow:     0 1px 2px rgba(0, 0, 0, .45), 0 6px 18px rgba(0, 0, 0, .35);
  --pf-shadow-lg:  0 2px 6px rgba(0, 0, 0, .5), 0 20px 46px rgba(0, 0, 0, .55);

  --pf-m1: #3E7355;  --pf-m1-hi: #E2B252;
  --pf-m2: #3F7A7C;  --pf-m2-hi: #86C6BC;
  --pf-m3: #5C8663;  --pf-m3-hi: #AFC298;
  --pf-m4: #B75F3E;  --pf-m4-hi: #E9A877;

  color-scheme: dark;
}

/* ═══ RESET ═══ */
*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--pf-ground);
  color: var(--pf-ink);
  font-family: var(--pf-sans);
  font-size: var(--pf-fs-base);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

[hidden] { display: none !important; }

a { color: var(--pf-signal); text-decoration: none; }
a:hover { text-decoration: underline; }

:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--pf-signal);
  outline-offset: 2px;
  border-radius: 3px;
}

/* ═══ HEADER ═══ */
.pf-header {
  border-bottom: 1px solid var(--pf-line-2);
  background: var(--pf-surface);
}
.pf-header-inner {
  max-width: 1120px;
  margin: 0 auto;
  padding: 16px 28px;
  display: flex;
  align-items: center;
  gap: 20px;
}

.pf-brand { display: flex; align-items: baseline; gap: 10px; text-decoration: none; }
.pf-brand:hover { text-decoration: none; }
.pf-brand-mark {
  font-family: var(--pf-mono);
  font-size: var(--pf-fs-sm);
  font-weight: 600;
  letter-spacing: .04em;
  color: var(--pf-signal-ink);
  background: var(--pf-ink);
  padding: 4px 8px;
  border-radius: var(--pf-radius-sm);
}
:root[data-pf-theme="dark"] .pf-brand-mark,
:root:not([data-pf-theme="light"]) .pf-brand-mark { }
.pf-brand-name {
  font-size: var(--pf-fs-md);
  font-weight: 600;
  letter-spacing: -.012em;
  color: var(--pf-ink);
}
.pf-brand-sub {
  font-family: var(--pf-mono);
  font-size: var(--pf-fs-xs);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--pf-ink-3);
}

.pf-header-spacer { flex: 1; }

.pf-header-nav { display: flex; align-items: center; gap: 6px; }
.pf-header-user {
  font-size: var(--pf-fs-sm);
  color: var(--pf-ink-3);
  margin-right: 4px;
  max-width: 220px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ═══ BUTTONS ═══ */
.pf-btn {
  font-family: var(--pf-sans);
  font-size: var(--pf-fs-sm);
  font-weight: 500;
  line-height: 1.2;
  padding: 9px 15px;
  border-radius: var(--pf-radius-sm);
  border: 1px solid var(--pf-line);
  background: var(--pf-surface);
  color: var(--pf-ink);
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  transition: background .16s var(--pf-ease), border-color .16s var(--pf-ease);
}
.pf-btn:hover { background: var(--pf-surface-2); text-decoration: none; }

.pf-btn-primary {
  background: var(--pf-ink);
  border-color: var(--pf-ink);
  color: var(--pf-ground);
}
.pf-btn-primary:hover { background: var(--pf-ink-2); border-color: var(--pf-ink-2); }

.pf-btn-quiet {
  background: transparent;
  border-color: transparent;
  color: var(--pf-ink-2);
}
.pf-btn-quiet:hover { background: var(--pf-surface-2); }

.pf-btn-block { width: 100%; justify-content: center; }

/* The way into the Management Portal. Given the signal colour because for the
   people who can see it, it is the most important control on the page. */
.pf-btn-manage {
  border-color: var(--pf-signal);
  color: var(--pf-signal);
  font-weight: 500;
}
.pf-btn-manage:hover { background: var(--pf-signal-soft); }
.pf-pending-dot {
  display: inline-block; margin-left: 2px; padding: 1px 6px;
  border-radius: 9px; font-size: 11px; font-weight: 600;
  font-variant-numeric: tabular-nums;
  background: var(--pf-signal); color: var(--pf-signal-ink);
}

/* ═══ MAIN / FOOTER ═══ */
.pf-main { flex: 1; width: 100%; max-width: 1120px; margin: 0 auto; padding: 44px 28px 72px; }
.pf-main-narrow { max-width: 560px; }

.pf-footer {
  border-top: 1px solid var(--pf-line-2);
  padding: 20px 28px;
  /* --pf-ink-4 is a 33%-alpha hairline token, and it measured 2.54:1 here —
     far under the 4.5:1 floor. Footer text is small, but it is text: the
     course name and the builder credit both live in it. */
  color: var(--pf-ink-3);
  font-size: var(--pf-fs-xs);
}
.pf-footer-inner {
  max-width: 1120px; margin: 0 auto;
  display: flex; flex-wrap: wrap; gap: 6px 18px; align-items: center;
}

/* ═══ TYPE ═══ */
.pf-eyebrow {
  font-family: var(--pf-mono);
  font-size: var(--pf-fs-xs);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--pf-ink-3);
  margin: 0 0 12px;
}
h1.pf-title {
  font-size: var(--pf-fs-2xl);
  font-weight: 600;
  letter-spacing: -.028em;
  line-height: 1.08;
  margin: 0 0 14px;
  text-wrap: balance;
}
h2.pf-heading {
  font-size: var(--pf-fs-lg);
  font-weight: 600;
  letter-spacing: -.018em;
  margin: 0 0 8px;
}
.pf-lede {
  font-size: var(--pf-fs-md);
  color: var(--pf-ink-2);
  max-width: 60ch;
  margin: 0 0 8px;
}
.pf-muted { color: var(--pf-ink-3); font-size: var(--pf-fs-sm); }

/* ═══ SECTION LABEL ═══ */
.pf-section-label {
  display: flex; align-items: center; gap: 14px;
  margin: 46px 0 20px;
}
.pf-section-label span {
  font-family: var(--pf-mono);
  font-size: var(--pf-fs-xs);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--pf-ink-3);
  white-space: nowrap;
}
.pf-section-label::after {
  content: ''; flex: 1; height: 1px; background: var(--pf-line-2);
}

/* ═══ MODULE GRID ═══════════════════════════════════════════════════════════
   The platform is monochrome; each card supplies its own --card-accent. That
   is the whole visual argument of this design — colour belongs to modules. */
/* Four modules, one row on a desktop — the grid states the same fact the
   headline does. Falls to 2 then 1 as the viewport narrows. */
.pf-modules {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(228px, 1fr));
  gap: 16px;
}
@media (max-width: 1040px) {
  .pf-modules { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
}

.pf-module {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--pf-surface);
  border: 1px solid var(--pf-line);
  border-radius: var(--pf-radius);
  padding: 22px 22px 20px;
  text-decoration: none;
  color: inherit;
  overflow: hidden;
  transition: transform .18s var(--pf-ease), box-shadow .18s var(--pf-ease),
              border-color .18s var(--pf-ease);
}

/* The accent rail. Only a live module gets a saturated one. */
.pf-module::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: var(--card-accent, var(--pf-line));
}

.pf-module-live:hover,
.pf-module-live:focus-visible {
  transform: translateY(-2px);
  box-shadow: var(--pf-shadow-lg);
  border-color: var(--card-accent, var(--pf-line));
  text-decoration: none;
}

.pf-module-soon {
  background: transparent;
  border-style: dashed;
}
.pf-module-soon .pf-module-title,
.pf-module-soon .pf-module-num { color: var(--pf-ink-3); }
.pf-module-soon:hover { border-color: var(--pf-ink-4); }

.pf-module-top {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 12px; margin-bottom: 14px;
}
.pf-module-num {
  font-family: var(--pf-mono);
  font-size: var(--pf-fs-xs);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--card-accent, var(--pf-ink-3));
}
.pf-module-title {
  font-size: var(--pf-fs-lg);
  font-weight: 600;
  letter-spacing: -.02em;
  line-height: 1.15;
  margin: 0 0 6px;
  text-wrap: balance;
}
.pf-module-desc {
  font-size: var(--pf-fs-sm);
  color: var(--pf-ink-3);
  line-height: 1.55;
  margin: 0 0 16px;
  flex: 1;
}

.pf-module-topics {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin: 0 0 18px; padding: 0; list-style: none;
}
.pf-module-topics li {
  font-size: var(--pf-fs-xs);
  color: var(--pf-ink-3);
  background: var(--pf-surface-2);
  border-radius: 3px;
  padding: 3px 7px;
}

.pf-module-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin-top: auto;
  padding-top: 14px; border-top: 1px solid var(--pf-line-2);
}
.pf-module-action {
  font-size: var(--pf-fs-sm);
  font-weight: 500;
  color: var(--card-accent, var(--pf-ink-3));
  display: inline-flex; align-items: center; gap: 6px;
}
.pf-module-live:hover .pf-module-arrow { transform: translateX(3px); }
.pf-module-arrow { transition: transform .18s var(--pf-ease); }

/* ═══ STATE BADGES ═══
   The full set the platform will need. Phase 3 turns the rest on; they are
   defined now so the contract is visible and the styling exists when the
   access logic arrives. */
.pf-state {
  font-family: var(--pf-mono);
  font-size: 0.6875rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  font-weight: 500;
  padding: 3px 8px;
  border-radius: 3px;
  white-space: nowrap;
  border: 1px solid transparent;
}
.pf-state-available  { color: var(--pf-ok);    border-color: var(--pf-ok); }
.pf-state-continue   { color: var(--pf-signal-ink); background: var(--pf-signal); }
.pf-state-enrolled   { color: var(--pf-ok);    background: rgba(31,107,74,.1); border-color: var(--pf-ok); }
.pf-state-locked     { color: var(--pf-ink-3); border-color: var(--pf-line); }
.pf-state-expired    { color: var(--pf-danger); border-color: var(--pf-danger); }
.pf-state-soon       { color: var(--pf-ink-4); border-color: var(--pf-line); border-style: dashed; }

/* ═══ PANEL (auth cards, account, coming soon) ═══ */
.pf-panel {
  background: var(--pf-surface);
  border: 1px solid var(--pf-line);
  border-radius: var(--pf-radius);
  box-shadow: var(--pf-shadow);
  padding: 34px 32px 30px;
}
.pf-panel-centered { max-width: 420px; margin: 6vh auto 0; }

/* ═══ FORMS ═══ */
.pf-form { display: flex; flex-direction: column; gap: 18px; }
.pf-field { display: flex; flex-direction: column; gap: 6px; }
.pf-field label {
  font-family: var(--pf-mono);
  font-size: var(--pf-fs-xs);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--pf-ink-2);
}
.pf-field input {
  font-family: var(--pf-sans);
  font-size: var(--pf-fs-base);
  padding: 11px 13px;
  color: var(--pf-ink);
  background: var(--pf-ground);
  border: 1px solid var(--pf-line);
  border-radius: var(--pf-radius-sm);
  transition: border-color .16s var(--pf-ease);
}
.pf-field input:focus { border-color: var(--pf-signal); }
.pf-field input::placeholder { color: var(--pf-ink-4); }

.pf-help { font-size: var(--pf-fs-xs); color: var(--pf-ink-3); line-height: 1.5; margin: 0; }
.pf-help-error { color: var(--pf-danger); }

.pf-errors {
  background: var(--pf-danger-soft);
  border: 1px solid var(--pf-danger);
  border-left-width: 3px;
  border-radius: 0 var(--pf-radius-sm) var(--pf-radius-sm) 0;
  padding: 11px 14px;
  font-size: var(--pf-fs-sm);
  color: var(--pf-danger);
}
.pf-errors ul { margin: 0; padding-left: 16px; }
.pf-errors li + li { margin-top: 4px; }

.pf-notice {
  background: var(--pf-signal-soft);
  border: 1px solid var(--pf-signal);
  border-left-width: 3px;
  border-radius: 0 var(--pf-radius-sm) var(--pf-radius-sm) 0;
  padding: 12px 14px;
  font-size: var(--pf-fs-sm);
  color: var(--pf-ink-2);
  margin-bottom: 22px;
}
.pf-notice strong { color: var(--pf-ink); }

.pf-links {
  margin-top: 22px; padding-top: 18px;
  border-top: 1px solid var(--pf-line-2);
  display: flex; flex-wrap: wrap; gap: 8px 18px;
  font-size: var(--pf-fs-sm);
}

/* ═══ DEFINITION ROWS (account page) ═══ */
.pf-rows { display: flex; flex-direction: column; gap: 0; margin: 0 0 8px; }
.pf-row {
  display: flex; flex-wrap: wrap; gap: 4px 18px;
  padding: 13px 0;
  border-bottom: 1px solid var(--pf-line-2);
}
.pf-row:last-child { border-bottom: 0; }
.pf-row dt {
  font-family: var(--pf-mono);
  font-size: var(--pf-fs-xs);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--pf-ink-3);
  min-width: 140px;
  margin: 0;
}
.pf-row dd { margin: 0; color: var(--pf-ink); }

@media (max-width: 640px) {
  .pf-header-inner { padding: 14px 18px; gap: 12px; }
  .pf-brand-sub { display: none; }
  .pf-header-user { display: none; }
  .pf-main { padding: 30px 18px 56px; }
  .pf-panel { padding: 26px 20px 22px; }
  .pf-panel-centered { margin-top: 2vh; }
  .pf-row dt { min-width: 0; flex-basis: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   PLATFORM PAGES — composed around the artwork, not on top of it
   The supplied paintings are the subject; this stylesheet is the frame. Nothing
   here reconstructs an illustration.
   ═══════════════════════════════════════════════════════════════════════════ */

.pf-sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
html { background: var(--pf-ground); }
body { overflow-x: clip; }

.pf-title, .pf-heading, .pf-hero-title, .pf-page-title, .pf-worlds-title,
.pf-band-title, .pf-resume-title, .pf-login-title {
  font-family: var(--pf-serif); font-weight: 600; letter-spacing: -.01em;
}
.pf-kicker {
  font-size: .68rem; letter-spacing: .2em; text-transform: uppercase;
  color: var(--pf-ink-3); font-weight: 600; margin: 0 0 10px;
}

/* ═══ LOGO ═══ */
.pf-logo { display: inline-flex; align-items: center; }
.pf-logo-img { height: var(--logo-h, 34px); width: auto; display: block; }
.pf-logo-dark { display: none; }
:root[data-pf-theme="dark"] .pf-logo-light { display: none; }
:root[data-pf-theme="dark"] .pf-logo-dark { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-pf-theme="light"]) .pf-logo-light { display: none; }
  :root:not([data-pf-theme="light"]) .pf-logo-dark { display: block; }
}

/* ═══ HEADER ═══
   On the homepage it floats over the hero artwork, which already carries the
   brand lockup in its own corner — so ours stays out of the way until the
   artwork has scrolled past. Everywhere else it is a normal solid header. */
/* The header is sticky and 92 px tall on a phone, so anything the browser
   scrolls to — a keyboard focus move, or an in-page anchor — can land
   underneath it. `scroll-padding-top` is the documented fix for WCAG 2.2
   "Focus Not Obscured", and it costs nothing when nothing is obscured.

   The value has to track the header, which is not one height: measured at
   66px on desktop, 92px at 768, and 132px at 375 where it wraps to two rows.
   A single figure is wrong at two of those three — 104px cleared the desktop
   and tablet headers and sat 28px UNDER the phone one, which is the width
   where a covered control matters most.

   Measured today: no keyboard-reachable control on the current pages ends up
   under the header, so this is hardening rather than a repair. It stops being
   true the moment a page grows a control near the top of a scroll target. */
html { scroll-padding-top: 80px; }

.pf-header {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in srgb, var(--pf-surface) 84%, transparent);
  backdrop-filter: saturate(1.1) blur(10px);
  border-bottom: 1px solid var(--pf-line-2);
  transition: background var(--pf-t), border-color var(--pf-t);
}
.pf-header-inner { gap: 24px; padding-block: 12px; }

.pf-body-hero .pf-header {
  background: transparent; border-bottom-color: transparent; backdrop-filter: none;
}
/* The header lockup always shows.
   Hiding it and letting the artwork's own baked-in logo stand in was too
   fragile: the hero uses object-fit: cover, so which part of the painting is
   visible changes with every viewport — at some sizes the artwork's logo is
   cropped away and the page has no mark at all. The background is instead
   positioned so its logo is out of frame, and ours is the only one. */
.pf-body-hero.pf-scrolled .pf-header {
  background: color-mix(in srgb, var(--pf-surface) 88%, transparent);
  backdrop-filter: saturate(1.1) blur(10px);
  border-bottom-color: var(--pf-line-2);
}


.pf-nav { display: flex; align-items: center; gap: 10px; }
.pf-nav a {
  position: relative; padding: 8px 4px; font-size: var(--pf-fs-base);
  color: var(--pf-ink-2); letter-spacing: .005em;
  margin: 0 8px;
  transition: color var(--pf-t-fast);
}
.pf-nav a:hover { color: var(--pf-ink); text-decoration: none; }
.pf-nav a::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0;
  height: 2px; border-radius: 2px; background: var(--pf-green);
  transform: scaleX(0); transform-origin: left; transition: transform var(--pf-t);
}
.pf-nav a:hover::after { transform: scaleX(1); transform-origin: left; }
.pf-nav a[aria-current="page"] { color: var(--pf-ink); font-weight: 600; }
.pf-nav a[aria-current="page"]::after { transform: scaleX(1); }

.pf-theme-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; padding: 0; border: 1px solid var(--pf-line);
  border-radius: 50%; background: transparent; color: var(--pf-ink-2); cursor: pointer;
  transition: background var(--pf-t-fast), color var(--pf-t-fast), transform var(--pf-t-fast);
}
.pf-theme-toggle:hover { background: var(--pf-signal-soft); color: var(--pf-ink); }
.pf-theme-toggle:active { transform: scale(.92); }
.pf-theme-toggle .pf-icon-sun { display: none; }
:root[data-pf-theme="dark"] .pf-theme-toggle .pf-icon-sun { display: block; }
:root[data-pf-theme="dark"] .pf-theme-toggle .pf-icon-moon { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-pf-theme="light"]) .pf-theme-toggle .pf-icon-sun { display: block; }
  :root:not([data-pf-theme="light"]) .pf-theme-toggle .pf-icon-moon { display: none; }
}
.pf-avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: 50%;
  background: var(--pf-green); color: var(--pf-signal-ink);
  transition: transform var(--pf-t-fast);
}
.pf-avatar:hover { text-decoration: none; transform: translateY(-1px); }

/* ═══ MAIN ═══ */
.pf-main { max-width: 1180px; padding: 0 28px 110px; }
.pf-body-hero .pf-main { padding-top: 0; }

/* ═══ HERO — the supplied background, whole ═══ */
.pf-hero {
  position: relative;
  /* Full-bleed out of the centred main column. `100vw` counts the vertical
     scrollbar, so the page would scroll sideways by its width — `clip` on the
     body absorbs that without breaking the sticky header the way `hidden`
     would. */
  margin: calc(-1 * var(--pf-header-h, 62px)) calc(50% - 50vw) 0;
  width: 100vw;
  min-height: clamp(560px, 88vh, 900px);
  display: grid; align-items: center;
  overflow: hidden;
  isolation: isolate;
}
.pf-hero-bg { position: absolute; inset: -6% 0 -6%; z-index: 0; display: block; }
.pf-hero-bg img {
  width: 100%; height: 100%; object-fit: cover; object-position: 50% 68%;
  display: block; will-change: transform;
}
/* A whisper of the page ground at the bottom edge so the artwork hands over to
   the page instead of stopping at a line. */
.pf-hero::after {
  content: ''; position: absolute; inset: auto 0 0 0; height: 22%; z-index: 1;
  background: linear-gradient(to bottom, transparent, var(--pf-ground));
  pointer-events: none;
}

.pf-hero-copy {
  position: relative; z-index: 2;
  width: min(720px, calc(100% - 56px));
  margin-left: max(28px, calc(50% - 560px));
  /* Was symmetric padding, which left a lake of empty parchment above the
     eyebrow. The block now sits slightly high in the frame, the way a title
     page does. */
  padding: clamp(8px, 2vw, 24px) 0 clamp(28px, 5vw, 64px);
}
.pf-hero-eyebrow {
  font-size: var(--pf-fs-sm); letter-spacing: .44em; text-transform: uppercase;
  color: var(--pf-ink-3); margin: 0 0 10px;
}
.pf-hero-title {
  font-size: clamp(3.1rem, 1.4rem + 6.4vw, 6.4rem); line-height: .94;
  margin: 0 0 18px; color: var(--pf-green);
}
/* After dark the title is ivory, as in the approved night art direction. The
   brand green is raised at night so small text can hold contrast, which leaves
   it too quiet to carry a display line over a near-black ground. */
:root[data-pf-theme="dark"] .pf-hero-title { color: var(--pf-ink); }
@media (prefers-color-scheme: dark) {
  :root:not([data-pf-theme="light"]) .pf-hero-title { color: var(--pf-ink); }
}
.pf-hero-lede {
  font-size: clamp(1.25rem, 1rem + .8vw, 1.85rem); line-height: 1.25;
  color: var(--pf-ink); margin: 0 0 8px;
}
.pf-hero-sub { font-size: var(--pf-fs-md); color: var(--pf-ink-2); margin: 0; }
.pf-hero-actions {
  display: flex; gap: 14px; flex-wrap: wrap; align-items: center;
  margin: clamp(26px, 3.4vw, 40px) 0 0;
}
/* The one thing we want pressed. Bigger than a default button, with a shadow
   that lifts on hover rather than a colour that changes character. */
.pf-hero-actions .pf-btn-primary {
  padding: 13px 26px; font-size: var(--pf-fs-md); font-weight: 600;
  border-radius: 8px; box-shadow: 0 6px 18px rgba(31, 61, 46, .18);
}
.pf-hero-actions .pf-btn-primary:hover {
  transform: translateY(-2px); box-shadow: 0 10px 26px rgba(31, 61, 46, .24);
}
.pf-hero-actions .pf-btn-ghost { padding: 12px 20px; }

.pf-btn-ghost {
  background: transparent; border-color: var(--pf-green); color: var(--pf-green);
}
.pf-btn-ghost:hover { background: var(--pf-signal-soft); }

/* A hairline and a falling dot. The bordered "mouse" shape read as a control
   somebody had forgotten to style; this reads as an invitation. */
.pf-hero-scroll {
  position: absolute; left: 50%; bottom: 30px; z-index: 3; transform: translateX(-50%);
  width: 1px; height: 46px; background: var(--pf-line);
  display: block; opacity: .8;
}
.pf-hero-scroll span {
  position: absolute; left: -1.5px; top: 0;
  width: 4px; height: 4px; border-radius: 50%; background: var(--pf-sage);
  animation: pf-scroll-hint 2.4s var(--pf-ease) infinite;
}
.pf-hero-scroll:hover { opacity: 1; }
@keyframes pf-scroll-hint {
  0%       { transform: translateY(0);    opacity: 0; }
  22%      { opacity: 1; }
  78%      { opacity: 1; }
  100%     { transform: translateY(42px); opacity: 0; }
}

/* ═══ THE TURN — the hero has ended ═══ */
.pf-turn {
  display: flex; align-items: center; gap: 18px;
  max-width: 380px;
  /* The gap below is deliberately larger than the one above: the rule closes
     the hero, then the page takes a breath before the modules speak. */
  margin: clamp(56px, 9vw, 104px) auto clamp(72px, 11vw, 128px);
  color: var(--pf-sage);
}
.pf-turn-rule { flex: 1; height: 1px; background: var(--pf-line); }

/* ═══ FOUR WORLDS ═══ */
.pf-worlds-head { max-width: 640px; margin: 0 0 clamp(52px, 8vw, 96px); }
.pf-worlds-title {
  font-size: clamp(1.9rem, 1.3rem + 2vw, 3rem); line-height: 1.06;
  margin: 0 0 var(--pf-space-3); color: var(--pf-ink);
}
.pf-worlds-note { font-size: var(--pf-fs-md); color: var(--pf-ink-3); margin: 0; }

/* Each module gets its own room. The gap is larger than any gap inside a row,
   so four worlds never run into one another. */
.pf-bands { display: flex; flex-direction: column; gap: clamp(76px, 12vw, 156px); }
.pf-bands-page { margin-top: clamp(38px, 6vw, 66px); }

/* One module per band, alternating sides. Four worlds, not four boxes. */
/* The artwork leads: it takes the larger share and the text sits closer to it
   than to the page edge, so the two read as one object rather than two columns
   that happen to be adjacent. */
.pf-band {
  display: grid;
  grid-template-columns: minmax(0, 1.32fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(24px, 4vw, 52px);
}
.pf-band:nth-child(even) { grid-template-columns: minmax(0, 1fr) minmax(0, 1.32fr); }
.pf-band:nth-child(even) .pf-band-art { order: 2; }
.pf-band:nth-child(even) .pf-band-text { padding-right: clamp(0px, 3vw, 40px); }
.pf-band:nth-child(odd)  .pf-band-text { padding-left: clamp(0px, 1vw, 14px); }

.pf-band-art {
  position: relative; display: block; overflow: hidden;
  border-radius: var(--pf-radius-lg);
  aspect-ratio: 3 / 2;
  background: var(--pf-surface-2);
  box-shadow: var(--pf-shadow);
  /* The accent belongs to the module and shows as a hairline, not a wash. */
  outline: 1px solid color-mix(in srgb, var(--card) 26%, transparent);
  outline-offset: -1px;
}
.pf-band-art img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transform: scale(1.015);
  transition: transform 1.1s var(--pf-ease), filter var(--pf-t);
}
.pf-band-tint {
  position: absolute; inset: 0;
  background: linear-gradient(120deg,
              color-mix(in srgb, var(--card) 20%, transparent), transparent 62%);
  opacity: .8; transition: opacity var(--pf-t);
}
.pf-band:hover .pf-band-art img { transform: scale(1.055); }
.pf-band:hover .pf-band-tint { opacity: .45; }
/* The whole row is the hover target, so the artwork lifts with the text. */
.pf-band { transition: transform var(--pf-t); }
.pf-band:hover .pf-band-art { box-shadow: var(--pf-shadow-lg); }
.pf-band-art { transition: box-shadow var(--pf-t); }

.pf-band-index { display: flex; align-items: center; gap: 14px; margin: 0 0 16px; }
/* The numeral is the module's marker — set large, in its own colour, with a
   rule running off it so it reads as a chapter number rather than a label. */
.pf-band-num {
  position: relative;
  font-family: var(--pf-serif); font-size: 3.4rem; line-height: .8;
  color: var(--card); padding-right: 16px;
}
.pf-band-num::after {
  content: ''; position: absolute; right: 0; top: 12%; bottom: 12%;
  width: 1px; background: color-mix(in srgb, var(--card) 40%, transparent);
}
.pf-band-eyebrow {
  font-size: .68rem; letter-spacing: .2em; text-transform: uppercase;
  color: var(--pf-ink-3); font-weight: 600;
}
.pf-chip {
  font-size: .6rem; letter-spacing: .1em; text-transform: uppercase; font-weight: 600;
  padding: 3px 9px; border-radius: 3px;
  border: 1px solid var(--pf-line); color: var(--pf-ink-3);
}
.pf-chip-soon { border-style: dashed; }
.pf-chip-enrolled { color: var(--pf-ok); border-color: var(--pf-ok); }
.pf-chip-expired { color: var(--pf-warn); border-color: var(--pf-warn); }
.pf-chip-continue { color: var(--pf-green); border-color: var(--pf-green); }

.pf-band-title { font-size: clamp(1.95rem, 1.2rem + 2.1vw, 3rem); line-height: 1.02; margin: 0 0 14px; }
.pf-band-title a { color: var(--pf-ink); transition: color var(--pf-t-fast); }
.pf-band:hover .pf-band-title a { color: var(--card); }
.pf-band-title a:hover { text-decoration: none; }
.pf-band-desc { font-size: var(--pf-fs-lg); color: var(--pf-ink-2); margin: 0 0 20px; max-width: 44ch; }

.pf-band-topics {
  list-style: none; margin: 0 0 22px; padding: 0;
  display: flex; flex-wrap: wrap; gap: 8px;
}
/* Quieter than a pill: a hairline tag on the page, not a button. */
.pf-band-topics li {
  font-size: var(--pf-fs-xs); color: var(--pf-ink-3);
  border: 1px solid var(--pf-line-2); border-radius: 4px; padding: 5px 10px;
  background: color-mix(in srgb, var(--pf-surface) 60%, transparent);
}
.pf-band-go { margin: 0; }
/* A real destination, not a text link. It fills with the module's own colour
   on hover — the row's one clear affordance. */
.pf-band-link {
  display: inline-flex; align-items: center; gap: 10px;
  font-size: var(--pf-fs-sm); font-weight: 600; color: var(--card);
  padding: 10px 20px; border-radius: 7px;
  border: 1.5px solid color-mix(in srgb, var(--card) 42%, transparent);
  transition: background var(--pf-t), color var(--pf-t), border-color var(--pf-t);
}
.pf-band:hover .pf-band-link,
.pf-band-link:hover {
  text-decoration: none; background: var(--card); border-color: var(--card);
  color: #FBF7EF;
}
.pf-band-link svg { transition: transform var(--pf-t); }
.pf-band:hover .pf-band-link svg { transform: translateX(4px); }

/* Coming soon: unavailable, but still worth looking at. Desaturated a touch and
   set behind a hairline, rather than dimmed until it looks broken. */
.pf-band-art-soon img { filter: saturate(.78); }
.pf-band-art-soon::after {
  content: ''; position: absolute; inset: 0;
  background: color-mix(in srgb, var(--pf-ground) 26%, transparent);
}
.pf-chip-soon {
  border-style: solid; letter-spacing: .12em;
  color: var(--card); border-color: color-mix(in srgb, var(--card) 45%, transparent);
  background: color-mix(in srgb, var(--card) 8%, transparent);
}
.pf-band:has(.pf-band-art-soon) .pf-band-link {
  color: var(--pf-ink-3); border-color: var(--pf-line);
}
.pf-band:has(.pf-band-art-soon):hover .pf-band-link {
  background: transparent; color: var(--pf-ink-2); border-color: var(--pf-line);
}
.pf-band:has(.pf-band-art-soon):hover .pf-band-link svg { transform: none; }

/* ═══ CONTINUE LEARNING ═══ */
.pf-resume {
  display: flex; align-items: center; justify-content: space-between; gap: var(--pf-space-4);
  flex-wrap: wrap;
  margin-top: clamp(56px, 9vw, 104px);
  padding: var(--pf-space-4) var(--pf-space-5);
  border: 1px solid var(--pf-line); border-left: 3px solid var(--pf-amber);
  border-radius: var(--pf-radius); background: var(--pf-surface);
}
.pf-resume-title { font-size: 1.5rem; margin: 0 0 2px; color: var(--pf-ink); }
.pf-resume-sub { font-size: var(--pf-fs-sm); color: var(--pf-ink-3); margin: 0 0 12px; }
.pf-resume-meter {
  height: 5px; border-radius: 3px; background: var(--pf-surface-2);
  overflow: hidden; max-width: 400px;
}
.pf-resume-meter span { display: block; height: 100%; background: var(--pf-amber); }

/* ═══ VALUES — quiet and secondary ═══ */
.pf-values {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--pf-space-4);
  margin-top: clamp(64px, 10vw, 118px);
  padding-top: var(--pf-space-5);
  border-top: 1px solid var(--pf-line-2);
}
.pf-value { display: flex; flex-direction: column; gap: 4px; }
.pf-value svg { width: 20px; height: 20px; color: var(--pf-sage); margin-bottom: 6px; }
.pf-value b { font-size: var(--pf-fs-sm); font-weight: 600; color: var(--pf-ink); }
.pf-value span { font-size: var(--pf-fs-xs); color: var(--pf-ink-3); }

/* ═══ SIMPLE PAGES ═══ */
.pf-page-head { max-width: 640px; margin: clamp(38px, 6vw, 74px) 0 0; }
.pf-page-title { font-size: clamp(2.1rem, 1.4rem + 2.6vw, 3.4rem); line-height: 1.04; margin: 0 0 var(--pf-space-3); color: var(--pf-ink); }
.pf-page-lede { font-size: var(--pf-fs-md); color: var(--pf-ink-3); margin: 0; }

.pf-about {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, .82fr);
  gap: clamp(30px, 6vw, 76px); align-items: center;
  margin-top: clamp(38px, 6vw, 78px);
}
.pf-about-note { font-size: var(--pf-fs-sm); color: var(--pf-ink-3); margin: 18px 0 26px; }
.pf-about-art img {
  width: 100%; height: auto; border-radius: var(--pf-radius-lg);
  box-shadow: var(--pf-shadow); display: block;
}

/* ═══ BUTTONS ═══ */
.pf-btn { transition: background var(--pf-t-fast), border-color var(--pf-t-fast), transform var(--pf-t-fast); }
.pf-btn:active { transform: translateY(1px); }
.pf-btn-primary { background: var(--pf-green); border-color: var(--pf-green); color: var(--pf-signal-ink); }
.pf-btn-primary:hover { background: var(--pf-green-2); border-color: var(--pf-green-2); }

/* ═══ MOTION ═══ */
/* The stagger is 110ms, not 80: five hero lines at 80ms span 320ms, which the
   eye reads as one movement rather than five. At 110 they arrive as a sequence,
   which is the point of numbering them. */
.pf-motion [data-reveal] {
  opacity: 0; transform: translateY(18px);
  transition: opacity .6s var(--pf-ease), transform .6s var(--pf-ease);
  transition-delay: calc(var(--reveal-delay, 0) * 110ms);
}
.pf-motion [data-reveal].pf-revealed { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .pf-motion [data-reveal] { opacity: 1; transform: none; transition: none; }
  .pf-hero-bg img { transform: none !important; }
  .pf-hero-scroll span { animation: none; }
  .pf-band-art img, .pf-band-link svg, .pf-btn, .pf-nav a::after, .pf-band-tint { transition: none; }
  /* 1.015 is not a reduced lift — it is the artwork's RESTING scale (it sits
     slightly over its box so no hairline of background shows at the edge).
     Repeating it here pins hover to the resting value, so the image does not
     move at all. `transform: none` would be the bug: it would shrink the
     artwork by 1.5% on hover, which is movement in the opposite direction.
     The hover still reads, because the tint changes opacity — and opacity is
     not motion. */
  .pf-band:hover .pf-band-art img { transform: scale(1.015); }
}

/* ═══ RESPONSIVE ═══ */
@media (max-width: 1000px) {
  html { scroll-padding-top: 108px; }   /* header measures 92px here */
  .pf-band, .pf-band:nth-child(even) { grid-template-columns: 1fr; gap: var(--pf-space-3); }
  .pf-band:nth-child(even) .pf-band-art { order: 0; }
  .pf-band-art { aspect-ratio: 16 / 9; }
  .pf-values { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--pf-space-4) var(--pf-space-3); }
  .pf-about { grid-template-columns: 1fr; }
  .pf-about-art { max-width: 420px; }
}
@media (max-width: 760px) {
  html { scroll-padding-top: 148px; }   /* header wraps to two rows: 132px */
  .pf-main { padding: 0 18px 76px; }
  /* Two rows, because the three nav items plus the account controls need 564px
     and the phone has 375. Measured, not guessed — so the wrap is deliberate.
     What is trimmed instead is the height: a sticky header was taking 109px of
     an 812px screen, and this brings it under 90 without crowding anything. */
  .pf-header-inner { flex-wrap: wrap; gap: 6px; padding-block: 8px; }
  .pf-nav { order: 3; width: 100%; overflow-x: auto; scrollbar-width: none; gap: 4px; }
  .pf-nav a { margin: 0 3px; padding: 5px 3px; font-size: var(--pf-fs-sm); }
  .pf-nav::-webkit-scrollbar { display: none; }
  .pf-header-spacer { display: none; }
  /* The header can no longer float: it is two rows tall and would cover the
     artwork's own lockup. */
  .pf-body-hero .pf-header { background: var(--pf-surface); }
  .pf-body-hero .pf-header { border-bottom-color: var(--pf-line-2); }
  .pf-hero { min-height: 74vh; margin-top: 0; }
  .pf-hero-copy { margin-left: 18px; width: calc(100% - 36px); }
  .pf-hero-bg img { object-position: 62% 45%; }
  .pf-hero-scroll { display: none; }
}
@media (max-width: 520px) {
  .pf-values { grid-template-columns: 1fr; }
  .pf-band-num { font-size: 2rem; }
  .pf-resume { flex-direction: column; align-items: flex-start; }
}

/* ── Module access state on the account page ──
   A word, not a coloured pill: the dates matter more than the badge, and this
   is the only place a student can learn how long is left. */
.pf-access-state {
  font-weight: 600;
  font-size: var(--pf-fs-sm);
  letter-spacing: .01em;
}
.pf-access-open  { color: var(--pf-ok); }
.pf-access-ended { color: var(--pf-ink-3); }
.pf-access-soon  { color: var(--pf-warn); font-weight: 600; }

/* ═══ BUILDER CREDIT ═══
   Codeino's mark in the footer. Deliberately the quietest thing on the page:
   it sits after Dr. Baya's wordmark, at a fraction of its size, and slightly
   faded until you look at it. A student came here for chemistry, not for the
   agency that built the site — but the work should still be signed. */
.pf-footer-inner { justify-content: space-between; }
.pf-footer-brand { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center; }

.pf-built-by {
  display: inline-flex; align-items: center; gap: 9px;
  color: var(--pf-ink-3);
  font-size: var(--pf-fs-xs);
  white-space: nowrap;
}
/* The mark stays 21px because it has to read as quieter than Dr. Baya's 34px
   wordmark — but 21px is also the whole tap target, under the 24px minimum.
   Padding grows what a finger can hit; the negative margin cancels the layout
   effect, so nothing on the footer moves and the mark is the size it was. */
.pf-built-by a {
  display: inline-flex; align-items: center;
  padding: 6px 5px; margin: -6px -5px;
  border-radius: 6px;
}
.pf-built-by img {
  height: 21px; width: auto; display: block;
  opacity: .72;
  transition: opacity var(--pf-t);
}
.pf-built-by:hover img { opacity: 1; }

/* At night the mark's navy sits too close to the deep green ground. Rather than
   recolour somebody's logo, it gets a faint plate to stand on — the artwork is
   untouched, it just stops being asked to fight the background. */
:root[data-pf-theme="dark"] .pf-built-by img {
  background: rgba(242, 233, 216, .92);
  border-radius: 5px;
  padding: 4px 7px;
  opacity: .85;
}
:root[data-pf-theme="dark"] .pf-built-by:hover img { opacity: 1; }
@media (prefers-color-scheme: dark) {
  :root:not([data-pf-theme="light"]) .pf-built-by img {
    background: rgba(242, 233, 216, .92);
    border-radius: 5px;
    padding: 4px 7px;
    opacity: .85;
  }
  :root:not([data-pf-theme="light"]) .pf-built-by:hover img { opacity: 1; }
}

@media (max-width: 620px) {
  .pf-footer-inner { justify-content: center; text-align: center; }
  .pf-footer-brand { justify-content: center; }
}

@media (prefers-reduced-motion: reduce) {
  .pf-built-by img { transition: none; }
}
