/* ============================================================
   The vault - page-specific layout.
   Section-by-section translation of the approved Claude Design
   prototype (project/The Vault.dc.html) into real markup/CSS,
   reusing css/components.css and the shared shell rules in
   css/page.css (.navbar, .section, .split, .vault-card, .cta,
   .site-footer, etc.) wherever the visual is identical to Home.
   Only what's new to this page lives here.
   ============================================================ */

/* ---- Hero: every page after Home is 60vh, not 80vh -------------
   (Home keeps .hero at 80vh - see css/page.css.) */
.hero--sub { min-height: 60vh; }

/* ---- Live tools: left-aligned header, filter chips in their own row
   below -------------------------------------------------------------
   Was a row (heading+description beside the chips, wrapping to a
   column only once the two ran out of room to sit side by side):
   .tools-header__copy's flex:1;min-width:0 let it shrink indefinitely
   rather than ever forcing that wrap, so at any width with just enough
   room for both (desktop included), the chips sat to the right of a
   squeezed two-line heading instead of below it at full width. Always
   a column now, matching the design: heading+description read at full
   width, chips form their own row underneath at every screen size. */
.tools-header {
  width: 100%;
  max-width: var(--container-lg);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 24px;
}
.tools-header__copy { display: flex; flex-direction: column; gap: 16px; }
.tools-header__copy p,
.soon-header p {
  margin: 0;
  max-width: 560px;
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.5;
  color: var(--text-primary);
  text-wrap: pretty;
}
.tools-header__copy p { max-width: 900px; }
.soon-header {
  width: 100%;
  max-width: var(--container-lg);
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.soon-header p { max-width: 640px; }

/* #tools is .section--white (Coming soon stays .section--canvas below it,
   so the two don't read as one continuous grey block) - its vault-cards
   drop to the F9F9F9 block tone on white per page.css's --card-bg rule,
   which needs the sitewide "shadow only when white sits on white" rule
   (see the no-borders brief) since the section and card tones are barely
   distinguishable. Same shadow value as .section--white .app-shot /
   .brand-kit on Features. */
.section--white .vault-card { box-shadow: 0 24px 60px rgba(12, 8, 1, 0.12); }

/* Section headings on this page sit one step down the type scale
   (H3 / 44px) from Home's centered section headers (H2 / 52px):
   deliberate, matches the tighter left-aligned layout here. */
.vault-h2 {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 400;
  font-size: var(--text-h3);
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--text-primary);
  text-wrap: pretty;
}

.filter-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.filter-chip {
  padding: 8px 16px;
  /* border: 0 is load-bearing, not tidying - this is a native <button>,
     so dropping the old 1px outline left the UA's own default button
     border showing through. Shipped that way once. Any native control
     that stops declaring a border needs it zeroed explicitly. */
  border: 0;
  border-radius: 999px;
  cursor: pointer;
  font-family: var(--font-ui);
  font-size: 14px;
  line-height: 1.5;
  background: var(--card-bg);
  color: var(--text-primary);
  transition: background-color var(--duration-base) var(--ease-standard),
              color var(--duration-base) var(--ease-standard);
}
/* Selected is the ink ground, unselected the section's card fill:
   the chip never changes shape or gains an outline, only its tone. */
.filter-chip.is-active {
  background: var(--color-pickled-bluewood);
  color: var(--text-on-dark);
}

.tools-note { margin: 0; font-family: var(--font-body); font-size: 16px; line-height: 1.5; color: var(--text-secondary); }

/* ---- Live / coming-soon cards -----------------------------------
   Reuses .vault-card from page.css (same card the Home library
   teaser already uses) with two additions specific to this page's
   interactive grid: a hover lift + image zoom, and a dimmed image
   for not-yet-live tools. */
.tools-grid .vault-card,
.soon-grid .vault-card {
  transition: transform var(--duration-base) var(--ease-standard),
              box-shadow var(--duration-base) var(--ease-standard),
              opacity var(--duration-base) var(--ease-standard);
}
.tools-grid .vault-card:hover,
.soon-grid .vault-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 18px 40px rgba(12, 8, 1, 0.12);
}
.tools-grid .vault-card__media { transition: transform 400ms var(--ease-standard); }
.tools-grid .vault-card:hover .vault-card__media { transform: scale(1.03); }
.vault-card--soon .vault-card__media { opacity: 0.55; }
.vault-card[hidden] { display: none; }

/* ---- Bespoke tools: split layout, content left / photo right ---- */
.split__media--bespoke { min-height: 460px; }
/* This button's label is long enough to overflow its container at
   narrow widths - .bv-btn's white-space: nowrap (right for the site's
   usual short 2-4 word labels) doesn't shrink or wrap on its own; a
   flex item's default min-width: auto also blocks it from shrinking
   below its content's natural single-line width in the first place.
   Scoped to just this button rather than loosening .bv-btn generally,
   since nowrap pill-shaped buttons are correct everywhere else. */
#bespoke .split__actions .bv-btn--primary {
  white-space: normal;
  text-align: center;
  min-width: 0;
}
/* .tick-list (the checkmarked point list) lives in components.css:
   this page was its first use, How It Works reuses it twice more. */

/* ---- FAQ ---------------------------------------------------------- */
.faq-layout { width: 100%; max-width: var(--container-lg); display: flex; gap: var(--space-20); align-items: flex-start; }
.faq-layout__intro { flex: 0 0 380px; display: flex; flex-direction: column; gap: 16px; }
.faq-layout__body { flex: 1; }

.accordion { display: flex; flex-direction: column; width: 100%; }
.accordion__item { border-bottom: var(--border-width) solid var(--border-default); }
.accordion__item:first-child { border-top: var(--border-width) solid var(--border-default); }
.accordion__trigger {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 20px 0;
  background: transparent;
  border: 0;
  cursor: pointer;
  text-align: left;
  font: inherit;
  color: inherit;
  outline: none;
}
.accordion__question {
  flex: 1;
  font-family: var(--font-heading);
  font-size: 22px;
  line-height: 1.4;
  letter-spacing: -0.01em;
  color: var(--text-primary);
}
/* Hardcoded durations rather than --duration-base (which zeroes out
   below 768px, see the site's "mobile animations off" rule) - this is
   functional open/close feedback, not decorative motion, so it should
   stay animated on mobile the same way .field-reveal and
   .mobile-menu__children do (components.css / page.css). */
.accordion__icon { flex-shrink: 0; transition: transform 450ms var(--ease-standard); }
.accordion__item.is-open .accordion__icon { transform: rotate(45deg); }
/* max-height animation rather than the grid-template-rows 0fr->1fr
   trick used elsewhere (.field-reveal in components.css):
   display:none/block gave no transition to run at all, but the
   grid-rows trick doesn't work here specifically because the answer
   text's own padding-bottom (the gap before the divider below) lives
   on the child <p>: a grid item's padding is never suppressed by
   min-height:0/overflow:hidden the way its content height is, so the
   0fr row was still stuck at 20px (the padding) instead of fully
   collapsing to 0 - visible as a sliver of answer text left showing
   under every "closed" question. max-height on this element clips
   everything below it, padding included, regardless of what's inside.

   The open-state max-height itself is set inline by initAccordion()
   (main.js) from the panel's own measured scrollHeight at click time,
   not a fixed value here - answer text wraps to a different number of
   lines depending on viewport width (the FAQ layout column is much
   narrower on tablet/mobile than desktop), so a single hardcoded cap
   either clipped the last line off longer answers at narrow widths or
   sat mostly empty for short ones, throwing off both the padding at
   the bottom and how much of the transition's duration was actually
   spent revealing visible content. Measuring per click sidesteps both.
   linear rather than var(--ease-standard): that curve is a
   "decelerate" shape covering most of the visual distance in the
   first fraction of the duration, which read as too fast regardless
   of how long the duration was set to. Linear keeps the growth
   visibly even across the whole duration. */
.accordion__panel {
  max-height: 0;
  overflow: hidden;
  transition: max-height 500ms linear;
}
.accordion__panel > p {
  margin: 0;
  padding: 0 48px 32px 0;
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.5;
  color: var(--text-primary);
  text-wrap: pretty;
}

/* ---- CTA: same card as Home's final CTA, smaller heading + tighter gap */
.cta--tight .cta__card { gap: 16px; }
/* .cta__card h2's own -16px margin-top (page.css) is tuned against
   Home's plain .cta__card gap (32px), landing tagline->h2 at a
   readable 8px. This tighter 16px gap wasn't accounted for, so the
   same -16px pulled the heading up past the tagline entirely (16-8-16
   = -8px, an actual overlap) on every page using .cta--tight (every
   final CTA except Home's). Cancelled out here instead of touching the
   shared rule, landing back on that same 8px (16-8-0). */
.cta--tight .cta__card h2 { font-size: 38px; margin-top: 0; }
.cta--tight .cta__actions { margin-top: 16px; }

/* ---- Responsive --------------------------------------------------- */
@media (max-width: 960px) {
  /* align-items: stretch - same fix as .split/.hero__inner above: the
     base rule's flex-start is for the row layout (top-aligns the two
     side-by-side halves), and left in place through the switch to
     column here it sizes .faq-layout__intro to its own content width
     instead of the full stacked width, cramping its heading into a
     narrow column with far more room actually available beside it. */
  .faq-layout { flex-direction: column; align-items: stretch; gap: var(--space-16); }
  .faq-layout__intro { flex: none; }
  /* Header-to-content spacing convention (see page.css) - .faq-layout's
     own gap (--space-16, 64px) is too much between the intro and the
     first question, same 32px target as everywhere else on the site. */
  .faq-layout__body { margin-top: -32px; }
  /* .hero--sub itself is relaxed here, not in page.css's own ≤960 block
     - this file's <link> loads after page.css's (separate tag, not part
     of styles.css's @import chain), so an override placed there would
     lose to this file's unconditional 60vh rule regardless of media
     query, the same footgun the ≤640 fix above already hit. */
  .hero--sub { min-height: auto; }
}
@media (max-width: 640px) {
  .tools-grid, .soon-grid { grid-template-columns: 1fr; }
  .accordion__panel > p { padding-right: 0; }
  .cta--tight .cta__card h2 { font-size: 30px; }
  /* .hero--sub's 60vh min-height above is unconditional and this file
     loads after page.css (a separate <link>, not part of styles.css's
     @import chain), so it was winning over page.css's own
     ".hero { min-height: auto }" mobile reset regardless of viewport:
     forcing every sub-page hero to stay at least 60vh tall on mobile
     even when its content is much shorter than that (most visible on
     pages like Contact with a single button and a short paragraph:
     acres of dead space between the copy and the hero image below it). */
  .hero--sub { min-height: auto; }
}

/* Mobile animations-off (see page.css's own ≤767px block for the full
   rationale) - this one's a hardcoded 400ms, not --duration-base, so it
   needs its own override rather than inheriting that token's mobile
   zero. */
@media (max-width: 767px) {
  .tools-grid .vault-card__media { transition-duration: 0.01ms; }
}
