/* ═══════════════════════════════════════════════════════════════════
   DataraFlow public site
   One world for every page a visitor can reach without signing in:
   paper background, navy ink, a single brand-blue accent, Bricolage
   Grotesque, soft 8px controls and 18px panels, navy-tinted shadows.
   Tokens live in df-tokens.css and the shared .df-* components in
   df-core.css; this file holds only what is public: the base type,
   sections, the page-head air, Bootstrap overrides on public markup,
   the motion, and the navbar/footer. Loaded by public_base.html on
   `body.public`; the portal pages never load it. See DESIGN.md.
   ═══════════════════════════════════════════════════════════════════ */

/* ── Base ───────────────────────────────────────────────────────── */
/* Light mode on the public site: near-white page and a neutral soft grey
   for panels, instead of the portal's blue-grey paper (approved 30 Sept,
   after quickfleet.co). Dark mode: panels are the raised step of the neutral
   ramp (--df-public-panel, #111113), one above the page. */
:root:not([data-theme="dark"]) body.public { --df-paper: var(--df-public-paper); --df-panel: var(--df-public-panel); }
[data-theme="dark"] body.public { --df-panel: var(--df-public-panel); }

body.public {
    /* Body text is Inter (variable) everywhere; Bricolage is for display headings only (Tassy, 9 Oct). */
    font-family: var(--df-font-text);
    font-optical-sizing: auto;
    background: var(--df-paper);
    color: var(--df-ink);
    -webkit-font-smoothing: antialiased;
    scroll-behavior: smooth;
    line-height: 1.55;
}
body.public ::selection { background: var(--df-accent); color: var(--df-on-status); }
body.public :focus-visible { outline: 2px solid var(--df-accent); outline-offset: 3px; border-radius: 4px; }
body.public h1, body.public h2, body.public h3, body.public h4 {
    text-wrap: balance; letter-spacing: -.028em; line-height: 1.05; font-weight: 700; color: var(--df-ink);
}
/* The type system (tokens in df-tokens.css, spec in docs/DESIGN_SYSTEM.md
   section 3). Every public h1 is a hero headline and every h2 a section
   headline, both in the display face. Page stylesheets may colour, space
   and align them, never resize them. A small in-panel title that happens
   to be an h2 opts out with .df-h3. */
body.public h1, body.public h2 {
    font-family: var(--df-font-display); font-weight: var(--df-display-weight);
    font-stretch: var(--df-display-stretch); font-variation-settings: var(--df-display-wdth);
    text-transform: uppercase; line-height: var(--df-display-lh); letter-spacing: var(--df-display-ls);
}
body.public h1 { font-size: var(--df-type-hero); }
body.public h2 { font-size: var(--df-type-h2); }
body.public h3, body.public h2.df-h3 {
    font-family: var(--df-font-text); font-weight: 600; font-size: var(--df-type-h3); line-height: var(--df-type-h3-lh);
    letter-spacing: -.01em; text-transform: none; font-stretch: normal; font-variation-settings: normal;
}
/* The hero intro paragraph on every page. */
body.public .df-type-lede { font-family: var(--df-font-text); font-size: var(--df-type-lede); line-height: var(--df-type-lede-lh); font-weight: 400; }
body.public h4 { font-size: 1.1rem; }
body.public p { text-wrap: pretty; }
body.public main { padding-top: var(--df-nav-h); }
body.public .skip-link:focus { background: var(--df-ink); color: var(--df-paper); }
/* Sections and the page-head air are the public site's; portals are denser. */
.df-section { padding: 5.5rem 0; }
.df-section-tight { padding: 3.5rem 0; }
.df-section-surface { background: var(--df-surface); border-top: 1px solid var(--df-line); border-bottom: 1px solid var(--df-line); }
.df-section-intro { color: var(--df-ink-2); font-size: 1.12rem; max-width: 60ch; line-height: 1.55; margin: 0 0 2.6rem; }
.df-section-head { display: flex; flex-wrap: wrap; align-items: end; justify-content: space-between; gap: 1rem 2rem; margin-bottom: 2.4rem; }
.df-section-head h2 { margin: 0; }
.df-section-head p { margin: .5rem 0 0; color: var(--df-ink-2); max-width: 60ch; }
body.public .df-page-head { padding: 4.5rem 0 3rem; }
/* The old-style page head (scholarships, impact, donors, repository, legal,
   the scholarship forms) takes the shared hero lede. */
body.public .df-page-head .df-lede { font-family: var(--df-font-text); font-size: var(--df-type-lede); line-height: var(--df-type-lede-lh); }

/* ── Buttons on untouched Bootstrap markup ──────────────────────── */
/* Bootstrap buttons that survive on untouched markup take the same shape. */
body.public .btn { border-radius: var(--df-radius-ctl); font-weight: 600; font-family: inherit; transition: background-color 200ms var(--df-ease), border-color 200ms var(--df-ease), transform 160ms var(--df-ease); }
body.public .btn:active { transform: scale(.98); }
/* Buttons are pills on every public page (DESIGN_SYSTEM.md 2.7; Tassy,
   2026-10-09: "Verify certificate is not rounded, but other buttons are").
   The legacy .df-btn, Bootstrap .btn and the error page's .error-btn used
   --df-radius-ctl (8px). Buttons joined to a field keep their square join. */
body.public .df-btn,
body.public .btn:not(.btn-link):not(.input-group > .btn):not(.btn-group > .btn),
body.public .error-btn { border-radius: 999px; }
body.public .btn-primary { background: var(--df-accent); border-color: var(--df-accent); }
body.public .btn-primary:hover, body.public .btn-primary:focus { background: var(--df-accent-deep); border-color: var(--df-accent-deep); }
body.public .btn-outline-primary { color: var(--df-accent-deep); border-color: var(--df-line-strong); }
body.public .btn-outline-primary:hover { background: var(--df-accent-soft); color: var(--df-accent-deep); border-color: var(--df-accent-deep); }
body.public .btn-outline-secondary { color: var(--df-ink); border-color: var(--df-line-strong); }
body.public .btn-outline-secondary:hover { background: var(--df-surface); color: var(--df-ink); border-color: var(--df-ink); }

/* ── Tables and forms on untouched Bootstrap markup ─────────────── */
body.public .table { --bs-table-bg: transparent; --bs-table-border-color: var(--df-line); color: var(--df-ink); }
body.public .table th { color: var(--df-ink-3); font-weight: 600; font-size: .85rem; border-bottom-color: var(--df-line-strong); }
body.public .form-label { font-weight: 600; font-size: .95rem; color: var(--df-ink); margin: 0; }
body.public .form-text { color: var(--df-ink-3); font-size: .88rem; margin: 0; }
body.public .invalid-feedback { color: var(--df-danger); font-size: .88rem; font-weight: 500; margin: 0; }
body.public .form-control, body.public .form-select {
    font-family: inherit; font-size: 1rem; color: var(--df-ink);
    background: var(--df-surface); border: 1px solid var(--df-line-strong); border-radius: var(--df-radius-ctl);
    padding: .8rem .95rem; line-height: 1.35; width: 100%;
    transition: border-color 200ms var(--df-ease), box-shadow 200ms var(--df-ease);
}
body.public .form-control::placeholder { color: var(--df-ink-3); opacity: 1; }
body.public .form-control:focus, body.public .form-select:focus { outline: none; border-color: var(--df-accent); box-shadow: 0 0 0 4px var(--df-accent-soft); }
body.public .form-control.is-invalid { border-color: var(--df-danger); }
body.public .form-control.is-invalid:focus { box-shadow: 0 0 0 4px var(--df-danger-soft); }
body.public .form-control:disabled, body.public .form-select:disabled { background: var(--df-paper); color: var(--df-ink-3); }
body.public .form-check-input { width: 1.15em; height: 1.15em; border-color: var(--df-line-strong); margin-top: .2em; }
body.public .form-check-input:checked { background-color: var(--df-accent); border-color: var(--df-accent); }
body.public .form-check-input:focus { border-color: var(--df-accent); box-shadow: 0 0 0 4px var(--df-accent-soft); }
body.public .form-check-label { color: var(--df-ink-2); }
body.public .input-group-text { background: var(--df-paper); border-color: var(--df-line-strong); color: var(--df-ink-3); border-radius: var(--df-radius-ctl); }

/* Bootstrap leftovers that should not fight the world */
body.public .card { border: 1px solid var(--df-line); border-radius: var(--df-radius-panel); box-shadow: none; }
body.public .alert { border-radius: var(--df-radius-ctl); border: 0; }
body.public .alert-info { background: var(--df-accent-soft); color: var(--df-ink); }
body.public .alert-success { background: var(--df-ok-soft); color: var(--df-ok); }
body.public .alert-warning { background: var(--df-warn-soft); color: var(--df-warn); }
body.public .alert-danger { background: var(--df-danger-soft); color: var(--df-danger); }
body.public .badge { border-radius: var(--df-radius-tag); font-weight: 600; }
body.public .text-muted { color: var(--df-ink-3) !important; }
body.public .text-primary { color: var(--df-accent-deep) !important; }
body.public .bg-light { background: var(--df-paper) !important; }
body.public .modal-content { border-radius: var(--df-radius-panel); border: 1px solid var(--df-line); }
body.public .pagination .page-link { color: var(--df-ink); border-color: var(--df-line); }
body.public .pagination .active .page-link { background: var(--df-accent); border-color: var(--df-accent); }

/* ── Motion ─────────────────────────────────────────────────────── */
/* Two authored moments: the page head rises on load, and each section
   rises the first time it scrolls into view (static/js/public.js adds
   .df-reveal and .is-in; grid children stagger through --i). Both are
   skipped entirely under prefers-reduced-motion. */
@media (prefers-reduced-motion: no-preference) {
    .df-rise { opacity: 0; transform: translateY(14px); animation: df-rise 700ms var(--df-ease) forwards; }
    .df-rise-2 { animation-delay: 80ms; }
    .df-rise-3 { animation-delay: 160ms; }
    body.public .df-page-head > * > * { opacity: 0; transform: translateY(14px); animation: df-rise 700ms var(--df-ease) forwards; }
    body.public .df-page-head > * > :nth-child(2) { animation-delay: 80ms; }
    body.public .df-page-head > * > :nth-child(3) { animation-delay: 160ms; }
    body.public .df-page-head > * > :nth-child(4) { animation-delay: 240ms; }
    body.public .df-page-head > * > :nth-child(n+5) { animation-delay: 300ms; }
    .df-reveal { opacity: 0; transform: translateY(18px); transition: opacity 700ms var(--df-ease), transform 700ms var(--df-ease); transition-delay: calc(var(--i, 0) * 60ms); }
    .df-reveal.is-in { opacity: 1; transform: none; }
    .df-people img, .df-avatar { transition: transform 500ms var(--df-ease); }
    .df-people li:hover img { transform: scale(1.03); }
}
@keyframes df-rise { to { opacity: 1; transform: none; } }
@media print { .df-reveal, .df-page-head > * > * { opacity: 1 !important; transform: none !important; animation: none !important; } }

/* ── Responsive (public air only; component breakpoints are in df-core.css) ── */
@media (max-width: 991px) {
    body.public .df-page-head { padding: 3rem 0 2.4rem; }
    .df-section { padding: 4.5rem 0; }
}
@media (max-width: 640px) {
    /* 3rem a side: 4rem left ~130px of blank ground between sections. */
    .df-section { padding: 3rem 0; }
    body.public .df-page-head { padding: 2.4rem 0 1.6rem; }
    .df-section-tight { padding: 2.5rem 0; }
}
