/* Styles the PHP site needs that the compiled Tailwind sheet does not contain.
 *
 * app.css is generated from the React build and only includes classes that
 * build actually used. Two things fall outside it:
 *
 *   .is-active, the class assets/js/app.js toggles on the selected tab. In
 *                 React the active state was inline style driven by component
 *                 state, so no class was ever emitted for Tailwind to see.
 *   .w-fit, used by a ported page; absent from the React class set.
 *
 * Keep this file small. Anything reusable belongs in the React source so both
 * implementations get it from the same place.
 */

.w-fit { width: fit-content; }

/* .h-auto, paired with w-full on the feature-page hero illustrations. React
 * never emitted it (it always sized images through a wrapper), so it tripped
 * check-php.py as an unstyled class.
 *
 * Nothing is visibly broken without it: those imgs carry width and height
 * attributes, so the browser derives an intrinsic aspect ratio and already
 * resolves height to auto. It is declared anyway so the class means what it
 * says, the moment one of those images loses its dimension attributes, the
 * presentational height hint would take over and stretch it. */
.h-auto { height: auto; }

/* .illus, the four practice-type illustrations wherever they appear as a set.
 *
 * The industry pages each open with one at its authored 1024x1024, which suits a
 * hero column. Everywhere the four are shown together, the industries index
 * cards and the homepage industry panels, a square is the wrong shape: it pushes
 * the card's actual copy off a phone screen entirely. A centred 3:2 window is
 * safe on all four, because every composition seats its subject in the middle
 * third with cream margin above and below, so the crop removes only background.
 *
 * This lives here rather than inline because app.css carries no object-fit or
 * aspect-ratio utility at all, the React build never emitted one, and three
 * templates need the identical treatment.
 *
 * No hover transform: the design system forbids scale or lift on interactive
 * state (specs/01), and these sit inside link cards. */
.illus {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  object-position: center;
}

/* Breakpoint variants the compiled sheet does not carry.
 *
 * app.css only contains classes the React build actually emitted, and React
 * never used these two, so the industry-page hero, which stacks a copy column
 * over an illustration on mobile and sits them side by side from lg up, was
 * rendering with its copy still centred and still carrying the mobile top
 * margin at desktop width. Silent failure: scripts/check-php.py only validates
 * unprefixed class names, so a missing `lg:` variant does not trip the gate.
 *
 * 64rem matches the `@media (width>=64rem)` block app.css uses for its own lg
 * utilities, read from the compiled sheet rather than assumed, so the two
 * cannot drift apart at the boundary. */
@media (width >= 64rem) {
  .lg\:text-left { text-align: left; }
  .lg\:mt-0 { margin-top: 0; }
}

/* Selected tab. Colour only, the design system forbids scale or lift on
 * interactive state (specs/01). */
[data-tab].is-active {
  background: #163327;
  color: #FAF8F3;
}

/* Gold-filled variants keep their own background; only the text needs fixing. */
[data-tab].is-active.bg-\[\#C9A84C\] {
  background: #C9A84C;
  color: #12291F;
}

/* .pill-champagne inside a selected tab.
 *
 * The pill is authored for a light surface: #8A6D28 text on a 14% gold wash.
 * Inside .is-active that wash composites over #163327 instead of bone, landing
 * the pair at 2.32:1, so the "two months free" badge, the one thing the
 * billing toggle exists to sell, was the least legible text on the pricing
 * page. app.css already ships an inverted treatment for dark surfaces under
 * .on-forest / .surface-forest, but a tab is not a forest section, so the
 * selected tab needs its own rule.
 *
 * Solid champagne-300 rather than the translucent wash: on a chip this small
 * a fill reads as a badge and a wash reads as noise, and it measures 9.63:1.
 * Asserted in scripts/check-contrast.py as "badge on selected tab". */
[data-tab].is-active .pill-champagne {
  background: #E8C98A;
  border-color: #E8C98A;
  color: #12291F;
}

/* Focus ring parity with the React build. */
[data-tab]:focus-visible,
[data-acc-trigger]:focus-visible {
  outline: 2px solid #A8863A;
  outline-offset: 2px;
}

/* Tab chips -------------------------------------------------------------
 *
 * Four homepage tab groups, industries, the bilingual conversation, features
 * and locations, used to render their *selected* appearance as an inline
 * style computed in PHP from $isFirst. Two consequences, both visible on the
 * live page:
 *
 *   1. app.js toggles .is-active, but an inline style outranks any class rule,
 *      so the highlight never moved. Clicking "Med Spas" swapped the panel
 *      while "Therapy" stayed lit, the open panel and the selected tab
 *      disagreed with each other.
 *   2. :hover could not apply for the same reason. Tabs elsewhere on the page
 *      are styled with Tailwind classes and did hover, so whether a tab
 *      responded to the pointer depended on which group it belonged to.
 *
 * PHP now passes only the accent, as custom properties, and encodes no state.
 * State lives here, where the cascade can resolve it.
 *
 * Specificity: [data-tab].is-active above fills the plain tab groups forest
 * green. Every selector here carries .tab-* as well, so it outranks that rule
 * on specificity rather than on source order. */
[data-tab].tab-chip {
  background: rgba(22, 51, 39, 0.05);
  border: 1px solid rgba(22, 51, 39, 0.11);
  color: #59665E;
}

[data-tab].tab-chip:hover {
  background: rgba(22, 51, 39, 0.09);
  border-color: rgba(22, 51, 39, 0.22);
  color: #163327;
}

[data-tab].tab-chip.is-active {
  background: var(--tab-wash);
  border-color: var(--tab-edge);
  color: var(--tab-accent);
}

/* The gold-filled conversation switch (English / Spanish). */
[data-tab].tab-gold {
  color: #59665E;
}

[data-tab].tab-gold:hover {
  background: rgba(138, 109, 40, 0.10);
  color: #163327;
}

[data-tab].tab-gold.is-active {
  background: #8A6D28;
  color: #FFFFFF;
}

/* The six feature cards, which are tabs shaped like cards. */
[data-tab].tab-card {
  background: #F6F3EE;
  border: 1px solid rgba(22, 51, 39, 0.10);
}

[data-tab].tab-card:hover {
  background: #F1ECE3;
  border-color: rgba(22, 51, 39, 0.20);
}

[data-tab].tab-card.is-active {
  background: rgba(201, 168, 76, 0.10);
  border-color: rgba(201, 168, 76, 0.35);
}

.tab-card-icon {
  color: #7C887F;
}

[data-tab].tab-card.is-active .tab-card-icon {
  color: #8A6D28;
}

/* Same freeze as the icon: the card title had its colour written inline from
 * $isFirst, so "Bilingual HIPAA Intake Forms" stayed gold whichever card was
 * actually selected. */
.tab-card-title {
  color: #59665E;
}

[data-tab].tab-card.is-active .tab-card-title {
  color: #8A6D28;
}

/* Feature preview mockups ------------------------------------------------
 *
 * The preview panel is near-black, rgba(7,12,26,0.95), but each mockup's
 * header row was authored for a light card and never updated: #163327 title
 * text above an #E3DBCD rule. On that panel the title was effectively
 * invisible, which is what the header row looked like on every feature.
 *
 * The status pill was worse. bg-[#2E5744]/12 is an opacity-modifier class the
 * compiled sheet never emitted, so the pill had no fill whatsoever and only
 * its dark-green text rendered, on near-black.
 *
 * check-contrast.py did not catch either one: it asserts a fixed list of
 * documented pairs and these were never on it. They are now. */
.mock-head {
  border-bottom: 1px solid rgba(255, 255, 255, 0.14);
}

.mock-title {
  color: #F1EDE4;
}

.mock-badge {
  background: rgba(232, 201, 138, 0.16);
  border: 1px solid rgba(232, 201, 138, 0.30);
  color: #E8C98A;
}

/* Blog definition callouts.
 *
 * They borrow .pill-champagne for its colours, but that class is a chip style:
 * 11px, bold, letter-spaced and text-transform:uppercase. All four inherit into
 * the callout's body, which is a full sentence, so every definition on the
 * blog has been rendering as a wall of uppercase since the port. The label
 * above it is meant to be uppercase and keeps the chip treatment. */
.def-body {
  text-transform: none;
  letter-spacing: normal;
  font-weight: 400;
}

/* Pointer feedback is a hover affordance, so it belongs with the states above
 * rather than being left to a utility class that only some groups carried. */
[data-tab] {
  cursor: pointer;
}

/* Tab strips scroll rather than stack on a phone.
 *
 * Four chips reading "Therapy & Mental Health", "Med Spas & Aesthetics" and so
 * on wrap to four near-full-width rows on a 390px screen, pushing the panel
 * they control off the fold. A single swipeable row keeps the control and its
 * result on the same screen. Above 640px they wrap as before. */
@media (width < 40rem) {
  .tab-strip {
    flex-wrap: nowrap;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    /* Bleed to the section's edges so the row reads as scrollable rather than
       as a cramped list that happens to be clipped. */
    margin-inline: -1.5rem;
    padding-inline: 1.5rem;
    padding-bottom: 0.25rem;
  }

  .tab-strip::-webkit-scrollbar {
    display: none;
  }

  .tab-strip > [data-tab] {
    flex: 0 0 auto;
    scroll-snap-align: start;
  }
}

/*
 * .nav-current, the navbar entry matching the current route.
 *
 * Neither implementation marked the active page: every route rendered a nav
 * whose six items were styled identically, so the header gave no indication of
 * where you were. Emitted alongside aria-current="page" so the cue is not
 * colour-only.
 */
.nav-current {
  color: #8A6D28;
  font-weight: 600;
}

nav .nav-current {
  position: relative;
}

nav .nav-current::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -8px;
  height: 2px;
  border-radius: 1px;
  /* #C9A84C is only 2.15:1 on the #FAF8F3 navbar. The champagne reads as an
     accent elsewhere but fails WCAG 1.4.11 as a state indicator, so the
     underline uses the same #8A6D28 as the label (4.60:1). */
  background: #8A6D28;
}
