/* usarmysfl.com prototype: mobile-first port of the four live pages.
   One typeface: Public Sans, per Andre 2026-09-21. Palette: Onward Ops navy and blues over a cool off-white; the Army
   gold appears once, as the thin service stripe under the header. */

:root {
  --navy-900: #0d1f33;
  --navy-800: #14304d;
  --navy-700: #1d4066;
  --blue-600: #2d6caf;
  --blue-500: #38ace7;
  --blue-050: #eef5fb;
  --gold: #ffcc01;
  --ink: #1c2733;
  --ink-soft: #4d5c6c;
  --paper: #f7f9fb;
  --card: #ffffff;
  --line: #dde5ec;
  --radius: 7px;
  --shadow: 0 1px 2px rgba(13, 31, 51, 0.05), 0 3px 10px rgba(13, 31, 51, 0.04);
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: "Public Sans", "Segoe UI", system-ui, sans-serif;
  font-size: 1.0625rem;
  line-height: 1.65;
}

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

h1, h2, h3 {
  font-family: "Public Sans", "Segoe UI", system-ui, sans-serif;
  line-height: 1.2;
  color: var(--navy-900);
  text-wrap: balance;
  margin: 0 0 0.6em;
}

h1 { font-size: clamp(1.9rem, 5.5vw, 3rem); font-weight: 800; }
h2 { font-size: clamp(1.4rem, 4vw, 2rem); font-weight: 700; }
h3 { font-size: 1.15rem; font-weight: 700; }

p { margin: 0 0 1em; }

a { color: var(--blue-600); }
a:hover { color: var(--navy-700); }

/* ── Header ──────────────────────────────────────────────────────────── */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(255, 255, 255, 0.94);
  backdrop-filter: blur(8px);
  border-bottom: 3px solid var(--gold);
}

.header-inner {
  max-width: 1080px;
  margin: 0 auto;
  padding: 10px 16px;
  display: flex;
  align-items: center;
  gap: 12px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  min-width: 0;
}

.brand img { height: 34px; width: auto; }

/* Hand-rolled disclosure nav: a checkbox, a burger, no scripts. */
.nav-toggle { position: absolute; opacity: 0; }

.nav-burger {
  margin-left: auto;
  width: 44px;
  height: 44px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 5px;
  cursor: pointer;
  border-radius: 10px;
}

.nav-burger:hover { background: var(--blue-050); }

.nav-burger span {
  display: block;
  width: 20px;
  height: 2px;
  background: var(--navy-800);
  border-radius: 2px;
  transition: transform 0.2s ease, opacity 0.2s ease;
}

.nav-toggle:checked ~ .nav-burger span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle:checked ~ .nav-burger span:nth-child(2) { opacity: 0; }
.nav-toggle:checked ~ .nav-burger span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.site-nav {
  display: none;
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  background: #ffffff;
  border-bottom: 1px solid var(--line);
  box-shadow: var(--shadow);
  padding: 8px 12px 12px;
}

.nav-toggle:checked ~ .site-nav { display: block; }

.site-nav a {
  display: block;
  padding: 12px 10px;
  border-radius: 10px;
  text-decoration: none;
  font-weight: 600;
  color: var(--navy-800);
}

.site-nav a:hover { background: var(--blue-050); }
.site-nav a[aria-current="page"] { color: var(--blue-600); background: var(--blue-050); }

/* "a.nav-cta" outranks ".site-nav a", which would win on a bare class
   and flatten the pill back to 10px. */
.site-nav a.nav-cta {
  margin-top: 6px;
  background: var(--blue-500);
  color: #ffffff !important;
  text-align: center;
  border-radius: 999px;
}

.nav-cta:hover { background: var(--blue-600) !important; }

@media (min-width: 760px) {
  .nav-burger { display: none; }
  .site-nav {
    display: flex;
    position: static;
    background: none;
    border: 0;
    box-shadow: none;
    padding: 0;
    margin-left: auto;
    align-items: center;
    gap: 2px;
  }
  .site-nav a { padding: 8px 14px; }
  .site-nav a.nav-cta { margin-top: 0; margin-left: 8px; }
}

/* ── Hero ────────────────────────────────────────────────────────────── */

.hero {
  position: relative;
  /* clip, not hidden: "hidden" would make the hero a scroll container,
     and the parallax layer's view() timeline would track IT instead of
     the page. */
  overflow: clip;
  background: var(--navy-900);
  color: #ffffff;
}

/* Two stacked layers: the photograph below, the gradient above. A real
   element, not a pseudo: view() timelines do not track pseudo-elements
   in current engines. It bleeds past the box so the parallax never
   shows an edge. */
.hero-bg {
  position: absolute;
  inset: -42% 0 0 0;
  background: url("assets/372.jpg") center / cover no-repeat;
}

.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(13, 31, 51, 0.82) 0%, rgba(20, 48, 77, 0.88) 100%);
}

/* The light 3D: as the hero scrolls out, its photograph drifts slower
   than the page and swells a touch, so the text reads as a nearer
   plane. Scroll-driven, on the compositor, no scripts; a browser
   without scroll timelines keeps the still hero. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .hero-bg {
      animation: hero-parallax linear both;
      animation-timeline: view();
      animation-range: exit 0% exit 100%;
    }
  }
}

@keyframes hero-parallax {
  /* Firefox has no scroll timelines yet and keeps the still hero;
     accepted (2026-09-21). */
  to { transform: translateY(32%) scale(1.14); }
}

.hero-inner {
  position: relative;
  z-index: 1;
  max-width: 1080px;
  margin: 0 auto;
  padding: 56px 20px 60px;
  text-align: center;
}

.hero h1 { color: #ffffff; margin-bottom: 0.4em; }

.hero .kicker {
  font-family: "Public Sans", "Segoe UI", system-ui, sans-serif;
  font-weight: 700;
  font-size: 0.8rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 14px;
}

.hero p.lead {
  max-width: 46rem;
  margin: 0 auto 1.4em;
  font-size: clamp(1rem, 2.6vw, 1.2rem);
  color: rgba(255, 255, 255, 0.92);
}

.page-hero .hero-inner { padding: 40px 20px 44px; }

/* ── Buttons ─────────────────────────────────────────────────────────── */

.btn {
  display: inline-block;
  background: var(--blue-500);
  color: #ffffff;
  font-weight: 700;
  font-size: 1.1rem;
  text-decoration: none;
  padding: 14px 34px;
  border-radius: 999px;
  box-shadow: 0 6px 18px rgba(56, 172, 231, 0.35);
  transition: transform 0.15s ease, background 0.15s ease;
}

.btn:hover { background: var(--blue-600); color: #ffffff; transform: translateY(-1px); }

.btn-note { margin-top: 10px; font-size: 0.85rem; color: rgba(255, 255, 255, 0.75); }

/* ── Sections ────────────────────────────────────────────────────────── */

.section { padding: 44px 20px; }

.section-inner { max-width: 1080px; margin: 0 auto; }

.section.tint { background: var(--blue-050); }

.prose { max-width: 46rem; margin: 0 auto; }
.prose img { border-radius: var(--radius); box-shadow: var(--shadow); margin: 24px 0 8px; }
.prose .caption { font-size: 0.9rem; color: var(--ink-soft); margin-bottom: 24px; }

/* ── Photograph parallax ─────────────────────────────────────────────
   The same light 3D the hero has, for the in-page photographs: the
   frame clips, the image inside is oversized and drifts as it crosses
   the viewport, so it reads as a deeper plane than the text. Clip, not
   hidden, for the hero's reason: "hidden" would make the frame a
   scroll container and the view() timeline would track IT instead of
   the page. A browser without scroll timelines keeps a still photo. */
.photo-parallax {
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: clip;
  margin: 24px 0 8px;
}

.photo-parallax img {
  display: block;
  width: 100%;
  /* Oversized so the drift never shows an edge: 1.25 leaves 12.5%
     bleed per side, and the drift below stays inside 10%. */
  transform: scale(1.25);
  border-radius: 0;
  box-shadow: none;
  margin: 0;
}

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .photo-parallax img {
      animation: photo-parallax linear both;
      animation-timeline: view();
      /* "contain": the drift runs only while the photograph is fully
         in view, so the whole travel happens over a short stretch of
         scrolling and reads as clearly as the hero's. The default
         range spread it across the entire viewport traverse, which
         was measurable and invisible at once. On a viewport shorter
         than the photograph the range collapses and the photo simply
         holds still, edges safely inside the bleed. */
      animation-range: contain;
    }
  }
}

@keyframes photo-parallax {
  from { transform: translateY(-10%) scale(1.25); }
  to { transform: translateY(10%) scale(1.25); }
}

/* The zoom variant: for a photograph whose subjects sit at the top
   edge, where the drift's crop would clip them. Anchored to the top
   center, the image simply grows as it scrolls, so the faces stay in
   frame the whole way; without scroll timelines it shows uncropped. */
.photo-parallax.zoom img {
  transform: none;
  transform-origin: 50% 0;
}

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .photo-parallax.zoom img { animation-name: photo-zoom; }
  }
}

@keyframes photo-zoom {
  from { transform: scale(1); }
  to { transform: scale(1.16); }
}

.closing {
  font-family: "Public Sans", "Segoe UI", system-ui, sans-serif;
  font-weight: 700;
  font-size: 1.2rem;
  color: var(--navy-800);
  border-left: 4px solid var(--gold);
  padding-left: 16px;
}

/* ── Benefit cards ───────────────────────────────────────────────────── */

.cards {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
  margin-top: 24px;
}

@media (min-width: 640px) { .cards { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1000px) { .cards { grid-template-columns: repeat(4, 1fr); } }

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 20px;
  box-shadow: var(--shadow);
  text-align: left;
}

.card .card-icon {
  width: 40px;
  height: 40px;
  /* Square, angled gradient: the lightness holds at the old flat
     tint's level while the hue drifts cyan to periwinkle. */
  background: linear-gradient(45deg, #c9edf8 0%, #ded8fb 100%);
  border-radius: 3px;
  color: var(--blue-600);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 12px;
}

.card h3 { margin-bottom: 0.35em; }
.card p { margin: 0; color: var(--ink-soft); font-size: 0.97rem; }

/* ── Partner strip ───────────────────────────────────────────────────── */

.partners {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 28px 48px;
  padding: 8px 0;
}

.partners img { height: 44px; width: auto; }
.partners img.tall { height: 64px; }
/* Face the Fight is a compact mark that reads larger than the wide Cohen
   lockup at equal height, so it runs shorter to balance visually. */
.partners img.ftf { height: 50px; }

.partners-label {
  text-align: center;
  font-family: "Public Sans", "Segoe UI", system-ui, sans-serif;
  font-weight: 700;
  font-size: 0.75rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 18px;
}

/* ── Quote (Contact) ─────────────────────────────────────────────────── */

.quote {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 20px 24px 18px;
  max-width: 46rem;
  margin: 0 auto;
}

/* The accent is the opening quotation mark itself, a nod to the old
   page's oversized glyph, instead of a colored border. */
.quote::before {
  content: "“";
  display: block;
  font-family: Georgia, "Times New Roman", serif;
  font-size: 64px;
  line-height: 1;
  height: 0.55em;
  color: var(--blue-600);
}

.quote p { font-style: italic; color: var(--ink); }
.quote footer { text-align: right; font-weight: 700; color: var(--navy-700); }

/* ── People (Contact) ────────────────────────────────────────────────── */

.people { display: grid; gap: 16px; margin-top: 20px; }
@media (min-width: 760px) { .people.two { grid-template-columns: 1fr 1fr; } }

.person {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 20px;
  display: flex;
  gap: 16px;
  align-items: flex-start;
}

.person img {
  width: 84px;
  height: 84px;
  object-fit: cover;
  border-radius: 50%;
  border: 3px solid var(--blue-050);
  flex-shrink: 0;
}

/* A long email must wrap inside the card, never widen the page. */
.person > div { min-width: 0; flex: 1; }
.person a { overflow-wrap: anywhere; }

/* A single person with a real bio: the card takes the page's prose
   measure instead of the full grid width, so the lines stay readable. */
.person.featured { max-width: 46rem; margin: 0 auto; }
.person.featured img { width: 110px; height: 110px; }

/* On a phone that bio was squeezed into a strip beside the photo. The
   photo keeps the name and role beside it as a head row; the bio and
   the email drop below it at the card's full width. The text wrapper
   dissolves (display: contents) so its children can place themselves
   on the card's own grid. */
@media (max-width: 639px) {
  .person.featured {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    /* The flex gap the base card sets would also open ROW gaps here,
       twice over thanks to the empty spanned row; margins space the
       rows instead. */
    gap: 0 14px;
    align-items: center;
  }
  .person.featured > img { grid-row: 1 / span 2; }
  .person.featured > div { display: contents; }
  .person.featured > div > * { grid-column: 1 / -1; }
  .person.featured > div > h3,
  .person.featured > div > .role { grid-column: 2; }
  .person.featured > div > p:not(.role) { margin-top: 12px; }
}

.person .role { color: var(--ink-soft); font-size: 0.92rem; margin-bottom: 0.3em; }
.person p { margin: 0 0 0.4em; font-size: 0.97rem; }

.committee {
  columns: 1;
  margin: 12px 0 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 640px) { .committee { columns: 2; } }

.committee li {
  padding: 8px 12px;
  margin-bottom: 8px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 7px;
  break-inside: avoid;
  font-size: 0.95rem;
}

/* Indented to the committee cards' own text inset, so the asterisk
   note reads as part of the list instead of floating left of it. */
.footnote { font-size: 0.85rem; color: var(--ink-soft); padding-left: 13px; margin-top: 2px; }

/* "How the program grows" lives in one centered card: heading, prose
   and the closing box together. */
.grow-card {
  max-width: 46rem;
  /* A little air below the card before the footer; the 36px above
     rides on the committee list in the same section. */
  margin: 36px auto 14px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 28px;
}

/* Alone in a section of its own (no committee above it), the section's
   padding sets the gap, not a second helping of margin. */
.section-inner > .grow-card:first-child { margin-top: 0; }

.grow-card h2 { margin-top: 0; }

.support-box {
  margin-top: 24px;
  background: var(--navy-800);
  color: #ffffff;
  border-radius: var(--radius);
  padding: 24px;
  text-align: center;
}

.support-box a { color: var(--blue-500); font-weight: 700; }

/* ── Footer ──────────────────────────────────────────────────────────── */

.site-footer {
  background: var(--navy-900);
  color: rgba(255, 255, 255, 0.72);
  font-size: 0.88rem;
  padding: 32px 20px;
  text-align: center;
}

.site-footer .footer-links { margin-top: 8px; }
.site-footer a { color: rgba(255, 255, 255, 0.9); text-decoration: none; margin: 0 8px; }
.site-footer a:hover { text-decoration: underline; }


/* ── Page transitions ────────────────────────────────────────────────
   Cross-document view transitions: pure CSS, and a browser without
   support simply navigates the old way. The header and footer hold
   still, the hero morphs between its tall and short shapes, and the
   rest of the page fades out and rises in. */

@view-transition { navigation: auto; }

.site-header { view-transition-name: site-header; }
.site-footer { view-transition-name: site-footer; }
.hero { view-transition-name: hero; }

::view-transition-old(root) {
  animation: vt-fade-out 160ms ease both;
}

::view-transition-new(root) {
  animation: vt-rise-in 320ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

::view-transition-group(hero) {
  animation-duration: 320ms;
  animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1);
}

@keyframes vt-fade-out {
  to { opacity: 0; }
}

@keyframes vt-rise-in {
  from { opacity: 0; transform: translateY(14px); }
}

/* Motion is a flourish, never a requirement. */
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

/* ── Load-in ─────────────────────────────────────────────────────────
   A view transition only runs when an old page exists; a direct URL
   visit has none, so a cold load gets its own entrance. The inline
   "pagereveal" listener in each page's head stamps html.vt-nav when a
   view transition is about to run, which stands this animation down so
   the two never play on top of each other. Browsers without the event
   never stamp the class and simply always get the load-in. */
@media (prefers-reduced-motion: no-preference) {
  html:not(.vt-nav) main {
    animation: page-load-in 480ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
  }
}

@keyframes page-load-in {
  from { opacity: 0; transform: translateY(14px); }
}


/* ── CMS content regions ─────────────────────────────────────────────
   The injected markup is intra's rendered output: plain elements, no
   classes. These rules make it read well inside the shell. */

.prose h2 { margin-top: 1.6em; }

.prose blockquote {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 20px 24px;
  margin: 0 0 1em;
  font-style: italic;
}

.prose ul, .prose ol { padding-left: 1.3em; }
.prose li { margin-bottom: 0.4em; }

.prose figure { margin: 24px 0; }
.prose figure img { border-radius: var(--radius); box-shadow: var(--shadow); }
.prose figcaption { font-size: 0.9rem; color: var(--ink-soft); margin-top: 6px; }

/* ── Designed accents over unclassed CMS markup ──────────────────────
   The home page's benefits list once got icon chips here by position;
   home is a TEMPLATE now (see content.js) and builds the designed
   .cards markup itself, so those rules are gone. What remains: any
   blockquote gets the big serif quotation mark the Contact page's
   quote card had, with the paragraph right after it as attribution. */

.prose blockquote::before {
  content: "“";
  display: block;
  font-family: Georgia, "Times New Roman", serif;
  font-style: normal;
  font-size: 64px;
  line-height: 1;
  height: 0.55em;
  color: var(--blue-600);
}

.prose blockquote + p {
  text-align: right;
  font-weight: 700;
  color: var(--navy-700);
}

/* The leadership portraits, a shell strip under the Contact content. */
.headshots {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 28px;
  margin-top: 8px;
}
.headshots figure { margin: 0; text-align: center; }
.headshots img {
  width: 96px;
  height: 96px;
  object-fit: cover;
  border-radius: 50%;
  border: 3px solid var(--blue-050);
  box-shadow: var(--shadow);
  margin: 0 auto;
}
.headshots figcaption { font-size: 0.85rem; color: var(--ink-soft); margin-top: 8px; max-width: 140px; }
