/* ============================================================
   tokens.css — FootCare Podiatry.

   This matches the original site's actual visual identity
   (green/white, Inter + Playfair Display, rounded corners, a
   real hero/about photo) rather than a new redesign — that's a
   deliberate choice for this build, not an oversight. The kit's
   normal "do real art direction, don't reuse the last client's
   look" rule is about not defaulting to BLOOM's or another
   client's palette for a NEW client. It doesn't apply here: this
   is the same client, and the brief was explicitly to keep the
   existing look and fix the code underneath it.
   ============================================================ */

:root {
  /* ---- Color — matches the deployed site ---- */
  --color-white:         #ffffff;
  --color-paper:         #f8f9f7;   /* body background   */
  --color-ink:           #1f2937;   /* primary text (gray-800) */
  --color-text-muted:    #4b5563;   /* gray-600 */
  --color-border:        #f3f4f6;   /* gray-100 */
  --color-green:         #166534;   /* primary accent    */
  --color-green-deep:    #14532d;   /* accent hover      */
  --color-green-soft:    #dcfce7;   /* pale green pill background */
  --color-star:          #fbbf24;   /* amber-400, review stars */
  --color-dark:          #1f2937;   /* footer background */
  --color-text-on-dark:  #d1d5db;

  /* ---- Type — matches the deployed site: Inter (body) +
     Playfair Display (headings). Loaded as one <link> in
     index.html, not @import (see base.css note for why). ---- */
  --font-display: "Playfair Display", Georgia, serif;
  --font-body: "Inter", -apple-system, "Segoe UI", sans-serif;

  /* ---- Spacing scale — reusable as-is ---- */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: 5rem;

  /* ---- Layout — reusable as-is ---- */
  --container-max: 72rem;
  --container-pad: clamp(1.5rem, 6vw, 5rem);
  --nav-height: 4.5rem;

  /* ---- Radius — rounded, matching the original's rounded-2xl /
     rounded-3xl treatment on buttons, cards and inputs. ---- */
  --radius-sm: 0.75rem;
  --radius-md: 1rem;
  --radius-lg: 1.5rem;
  --radius-pill: 999px;

  --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.06);
  --shadow-md: 0 12px 28px rgba(15, 23, 42, 0.10);

  --transition-fast: 150ms ease;
  --transition-base: 300ms cubic-bezier(0.4, 0, 0.2, 1);

  /* ---- Heading scale — reusable as-is ---- */
  --text-h1: clamp(2.25rem, 4.5vw, 3.5rem);
  --text-h2: clamp(1.75rem, 3vw, 2.5rem);
  --text-h3: 1.5rem;
  --text-h4: 1.125rem;

  /* Back-compat aliases so components.css (written against the
     generic boilerplate token names) needs no find/replace. */
  --color-bg: var(--color-white);
  --color-bg-alt: var(--color-paper);
  --color-bg-dark: var(--color-dark);
  --color-text: var(--color-ink);
  --color-accent: var(--color-green);
  --color-accent-dark: var(--color-green-deep);
}
/* ============================================================
   base.css — reset + element defaults. Reusable as-is.
   If a real bug shows up here, fix it here once — not in a
   per-client copy.
   ============================================================ */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* The nav is position: sticky and sits on top of the page at
     scroll position 0. Without this, scrolling or jumping to any
     anchor (native fragment navigation, scrollIntoView, the tabs
     links) lands the target flush with the very top of the
     viewport, which is *underneath* the nav bar — the target's
     own heading ends up hidden, and everything looks like it
     landed further down the page than it should have. This
     reserves that space for every anchor on the page, not just
     the ones the tabs script handles. */
  scroll-padding-top: var(--nav-height);
}

body {
  margin: 0;
  font-family: var(--font-body);
  color: var(--color-text);
  background: var(--color-bg);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  margin: 0;
  font-family: var(--font-display);
  line-height: 1.15;
}

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

p {
  margin: 0;
}

ul, ol {
  margin: 0;
  padding: 0;
  list-style: none;
}

a {
  color: inherit;
  text-decoration: none;
}

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

button {
  font-family: inherit;
  font-size: inherit;
  color: inherit;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}

input, textarea, select {
  font-family: inherit;
  font-size: inherit;
  color: inherit;
}

/* Visible keyboard focus everywhere. Don't remove this without
   replacing it with an equally visible alternative. */
:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* Respect reduced motion system-wide, in one place, instead of
   leaving every animated component (.card hover, [data-reveal],
   smooth scroll) to remember its own override. */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
/* ============================================================
   layout.css — primitives (.stack, .split, .grid-auto...).
   Reusable as-is across projects.

   Breakpoints — THE three values, reused everywhere in this kit.
   Don't introduce a fourth ad hoc value (a framework default
   like 768px, or a one-off like 760px) — that's exactly how
   layout drift crept into a past build.
     max-width: 640px   →  mobile
     max-width: 960px   →  tablet and down
     min-width: 961px   →  desktop and up
   ============================================================ */

.container {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--container-pad);
}

.container--narrow {
  max-width: 40rem;
}

.section {
  padding-block: var(--space-8);
}

.section--alt {
  background: var(--color-bg-alt);
}

.section--dark {
  background: var(--color-bg-dark);
  color: var(--color-text-on-dark);
}

@media (max-width: 640px) {
  .section {
    padding-block: var(--space-6);
  }
}

/* .stack — vertical rhythm between direct children. Children are
   forced to display:block for this — margin-top has no effect on
   an inline element (e.g. a bare <a>), which is what silently
   collapsed the footer's link lists onto one line on a past
   build: the markup was correct, the CSS just couldn't apply
   margin to an inline anchor. */
.stack > * + * {
  margin-top: var(--stack-gap, var(--space-5));
}

.stack > a {
  display: block;
}

.stack--tight > * + * {
  --stack-gap: var(--space-3);
}

.stack--loose > * + * {
  --stack-gap: var(--space-7);
}

/* .cluster — horizontal wrapping group (trust bars, tag lists) */
.cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--cluster-gap, var(--space-5));
}

.cluster--top {
  align-items: flex-start;
}

.cluster--loose {
  --cluster-gap: var(--space-7);
}

/* .text-center / .section-head — common heading treatment above a
   tabbed or card section: centered, with room below before the
   content starts. Named here so nobody reaches for an inline
   style for this, which is exactly the kind of ad hoc value this
   token/primitive system exists to avoid. */
.text-center {
  text-align: center;
}

.section-head {
  text-align: center;
  margin-bottom: var(--space-6);
}

/* .split — two columns, 50/50. Collapses at the SAME 960px
   breakpoint as everything else (a past build let this drift to
   a one-off 760px — fixed here so it can't happen again). */
.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-7);
  align-items: center;
}

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

/* .grid-auto — self-wrapping card/image grid, no fixed column
   count to manage at each breakpoint */
.grid-auto {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--space-6);
}

/* .grid-fixed-3 — locked 3-column grid (e.g. pricing tiers),
   steps down 3 → 2 → 1 at the shared breakpoints */
.grid-fixed-3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-6);
}

@media (max-width: 960px) {
  .grid-fixed-3 {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 640px) {
  .grid-fixed-3 {
    grid-template-columns: 1fr;
  }
}
/* ============================================================
   components.css — nav/button/card/tab/form/footer MECHANICS
   are reusable as-is. Colors, radius treatment, and whatever
   the signature element ends up being are project-specific and
   come from tokens.css, not from edits to this file.
   ============================================================ */

/* ---------- Nav ---------- */

.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--color-bg);
  border-bottom: 1px solid var(--color-border);
}

.nav.is-scrolled {
  box-shadow: var(--shadow-sm);
}

/* One real flex row — the bar and the mobile panel share this
   single wrapper instead of being separate sibling containers.
   (That mismatch is what misaligned nav links on a past build —
   fixed once, here, instead of per project.) */
.nav__inner {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--container-pad);
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: var(--nav-height);
  position: relative;
}

.nav__brand {
  font-family: var(--font-body);
  font-weight: 800;
  letter-spacing: -0.02em;
  font-size: 1.375rem;
  color: var(--color-accent);
}

.nav__links {
  display: none;
  align-items: center;
  gap: var(--space-6);
  font-size: 0.9375rem;
  font-weight: 500;
}

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

.nav__actions {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}

.nav__phone {
  display: none;
  font-weight: 500;
  color: var(--color-accent);
}

/* Plain text link, not a filled .btn--primary — a bordered/
   filled button looked too heavy at nav-bar scale on a past
   build. A real button here is a deliberate per-project choice,
   not the default. */
.nav__cta {
  display: none;
  font-weight: 600;
  color: var(--color-accent);
}

.nav__toggle {
  display: inline-flex;
  width: 2.25rem;
  height: 2.25rem;
  align-items: center;
  justify-content: center;
}

.nav__toggle-icon,
.nav__toggle-icon::before,
.nav__toggle-icon::after {
  content: "";
  display: block;
  width: 1.25rem;
  height: 2px;
  background: var(--color-text);
  transition: var(--transition-fast);
}

.nav__toggle-icon::before { transform: translateY(-6px); }
.nav__toggle-icon::after { transform: translateY(4px); }

/* Mobile dropdown panel exists in the DOM from page load and is
   shown/hidden purely by CSS reacting to a class nav.js toggles.
   Nothing gets injected at click time, so it can't stack
   duplicate panels if the toggle is tapped more than once — a
   real bug on a past build that rebuilt the menu's HTML on every
   click instead of toggling visibility. */
.nav__panel {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background: var(--color-bg);
  border-bottom: 1px solid var(--color-border);
  padding: var(--space-5) var(--container-pad);
  flex-direction: column;
  gap: var(--space-4);
}

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

.nav.is-open .nav__toggle-icon { background: transparent; }
.nav.is-open .nav__toggle-icon::before { transform: rotate(45deg); }
.nav.is-open .nav__toggle-icon::after { transform: rotate(-45deg); }

@media (min-width: 961px) {
  .nav__links { display: flex; }
  .nav__phone { display: block; }
  .nav__cta { display: inline-flex; }
  .nav__toggle { display: none; }
  .nav__panel { display: none !important; }
}

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-3) var(--space-6);
  border-radius: var(--radius-lg);
  font-weight: 600;
  font-size: 0.9375rem;
  transition: var(--transition-fast);
}

.btn--primary {
  background: var(--color-accent);
  color: var(--color-text-on-dark);
}

.btn--primary:hover {
  background: var(--color-accent-dark);
}

.btn--ghost {
  border: 1px solid var(--color-border);
  color: var(--color-text);
}

.btn--ghost:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.btn--on-photo {
  background: var(--color-white);
  color: var(--color-accent);
}

.btn--on-photo:hover {
  background: var(--color-paper);
}

.btn--block {
  display: flex;
  width: 100%;
}

/* ---------- Cards ---------- */

.card {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  transition: transform var(--transition-base),
              box-shadow var(--transition-base);
}

.card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-md);
}

.card h3 {
  font-size: 1.25rem;
  margin-bottom: var(--space-3);
}

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

.stars {
  display: flex;
  gap: 2px;
  margin-bottom: var(--space-4);
}

.stars svg {
  width: 1rem;
  height: 1rem;
  fill: var(--color-star);
}

.review-quote {
  font-style: italic;
  color: var(--color-ink);
}

/* ---------- Trust bar ---------- */

.trust-bar {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-6);
  padding-block: var(--space-5);
  border-bottom: 1px solid var(--color-border);
  font-size: 0.875rem;
  color: var(--color-text-muted);
}

.trust-bar__item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.trust-bar__item svg {
  width: 1.1rem;
  height: 1.1rem;
  fill: var(--color-accent);
  flex-shrink: 0;
}

/* ---------- Hero ----------
   Full-bleed photo with a dark overlay, matching the original.
   The original used a fixed height: 640px, which either cropped
   content on short viewports or left empty space on tall ones.
   Fixed here with min-height: clamp(...) instead — same general
   presence, but it adapts instead of being rigid. */

.hero {
  position: relative;
  display: flex;
  align-items: center;
  min-height: clamp(420px, 70vh, 640px);
  background-image:
    linear-gradient(rgba(15, 53, 36, 0.65), rgba(15, 53, 36, 0.75)),
    var(--hero-image, none);
  background-size: cover;
  background-position: center;
  background-color: var(--color-green-deep);
}

.hero__inner {
  max-width: 36rem;
}

.hero h1,
.hero p {
  color: var(--color-white);
}

.hero p {
  margin-top: var(--space-4);
  font-size: 1.125rem;
  color: rgba(255, 255, 255, 0.9);
}

.hero__meta {
  margin-top: var(--space-6);
  font-size: 0.875rem;
  color: rgba(255, 255, 255, 0.8);
}

.hero__actions {
  margin-top: var(--space-6);
}

.eyebrow + * {
  margin-top: var(--space-4);
}

/* ---------- Eyebrow tag ----------
   Two variants: the default light-green pill (used over a plain
   background, e.g. above the services heading) and --on-photo
   (translucent white, used over the hero photo where a dark-text
   pill needs contrast against a busy image instead of a flat
   background). */

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  background: var(--color-green-soft);
  border-radius: var(--radius-pill);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--color-accent);
}

.eyebrow--on-photo {
  background: rgba(255, 255, 255, 0.92);
  color: var(--color-ink);
  backdrop-filter: blur(4px);
}

.eyebrow .dot {
  color: var(--color-accent);
}

/* ---------- About photo ----------
   A real practitioner photo, not a placeholder — drop the actual
   file in at img/sarah.jpg (or repoint the src). */

.about-photo {
  aspect-ratio: 4 / 5;
  background: var(--color-bg-alt);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-md);
}

.about-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ---------- Tabs ----------
   Tab ↔ panel matching is done with id / aria-controls — the
   actual attribute, read by js/tabs.js — rather than a positional
   array mapping label order to panel order. A past build's array
   silently drifted out of sync with its markup; an attribute
   can't drift the same way. */

.tabs__list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-6);
  border-bottom: 1px solid var(--color-border);
  margin-bottom: var(--space-6);
}

.tabs__tab {
  padding: var(--space-3) 0;
  font-weight: 600;
  color: var(--color-text-muted);
  border-bottom: 2px solid transparent;
}

.tabs__tab[aria-selected="true"] {
  color: var(--color-accent);
  border-color: var(--color-accent);
}

.tabs__panel[hidden] {
  display: none;
}

/* ---------- Form ----------
   width: 100% on inputs/textareas isn't optional here — without
   it, a text input sizes to its own browser-default intrinsic
   width instead of filling its grid column, and on a past build
   that pushed the second field (Phone) past the edge of the form
   card entirely. min-width: 0 on the field and its grid parent
   stops the same class of overflow if a column ever gets narrow. */

.form-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}

.form-field label {
  font-size: 0.875rem;
  font-weight: 500;
}

.form-field .required {
  color: #b3261e;
}

.form-field input,
.form-field textarea {
  width: 100%;
  min-width: 0;
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-bg);
}

.form-field input:focus,
.form-field textarea:focus {
  border-color: var(--color-accent);
}

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

@media (max-width: 640px) {
  .form-grid {
    grid-template-columns: 1fr;
  }
}

/* ---------- Footer ---------- */

.site-footer {
  background: var(--color-bg-dark);
  color: var(--color-text-on-dark);
  padding-block: var(--space-8);
}

.site-footer a {
  opacity: 0.75;
}

.site-footer a:hover {
  opacity: 1;
}

.footer-grid {
  display: grid;
  grid-template-columns: 1.5fr 1fr 1fr;
  gap: var(--space-7);
}

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

@media (max-width: 640px) {
  .footer-grid {
    grid-template-columns: 1fr;
  }
}

/* ---------- Misc helper classes ----------
   A small, named set for the few layout cases the primitives
   above don't cover — kept here instead of reaching for inline
   styles, so spacing/color still come from tokens.css rather
   than from one-off values written into the markup. */

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

.h-compact {
  font-size: 1.25rem;
  margin-top: var(--space-6);
}

.text-link {
  color: var(--color-accent);
  text-decoration: underline;
}

.review-attribution {
  margin-top: var(--space-4);
  font-size: 0.875rem;
  color: var(--color-text-muted);
}

.label-accent {
  font-weight: 600;
  color: var(--color-accent);
  margin-bottom: var(--space-3);
}

.site-footer__brand {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.25rem;
  color: #fff;
}

.site-footer__heading {
  color: #fff;
  font-weight: 600;
}

.site-footer__legal {
  margin-top: var(--space-7);
  padding-top: var(--space-5);
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  font-size: 0.75rem;
}

/* ---------- Scroll reveal ----------
   Driven by js/reveal.js, which adds .reveal-pending itself before
   animating — [data-reveal] alone does NOT hide anything, so
   content stays visible if that script never runs. */

.reveal-pending {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity var(--transition-base),
              transform var(--transition-base);
}

.reveal-pending.is-visible {
  opacity: 1;
  transform: none;
}
