/* Reusable pieces: buttons, the hero slider, cards, accordion. */

/* --------------------------------------------------------------- buttons */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 15px 30px;
  font: 500 15px/15px var(--font);
  /* The page buttons carry a 2px white border. It is invisible against a white
     page but it is 4px of width and height, which is why they measured small. */
  border: 2px solid #fff;
  border-radius: var(--radius);
  transition: background-color .18s ease, color .18s ease;
}
.btn:hover { text-decoration: none; }

.btn--primary { background: var(--c-accent-deep); color: #fff; }
.btn--primary:hover { background: var(--c-accent-hover); color: #fff; }

.btn--ghost { background: transparent; color: #fff; box-shadow: inset 0 0 0 2px #fff; }
.btn--ghost:hover { background: #fff; color: var(--c-accent-deep); }

.btn--light { background: #fff; color: var(--c-accent-deep); }
.btn--light:hover { background: var(--c-surface-alt); color: var(--c-accent-hover); }

/* The header's pill. Deliberately a different shape from the page buttons. */
.btn--pill {
  padding: 12px 25px;
  /* 12 + 22 + 12 = the 46px pill the live header uses; the .btn shorthand's
     19px line-height would make it 43. Unlike the page buttons this one has no
     border — with one it measures 50. */
  font-size: 16px;
  line-height: 22px;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--c-accent);
  color: #fff;
}
.btn--pill:hover { background: var(--c-accent-hover); color: #fff; }

/* A smaller pill for the in-page calls to action: no border, tighter padding
   and a 30px radius rather than the full round. */
.btn--compact {
  padding: 12px 24px;
  font-size: 15px;
  line-height: 15px;
  border: 0;
  border-radius: 30px;
  background: #3852cc;
}

/* MarketBuilder's page buttons are pills. The exclusions matter: the header
   pill and the compact button are already shaped and this selector outweighs
   both of them. */
[data-brand="mb"] .btn:not(.btn--pill):not(.btn--compact) {
  padding: 15px 24px;
  font-size: 16px;
  line-height: 16px;
  border-radius: var(--radius-pill);
}

/* MB fills them with the lighter accent and draws the border in the same colour
   rather than white. The border still has to be there — it is 4px of the box —
   but on MB it is part of the fill instead of a white ring, so the two brands'
   buttons measure the same and only read differently. */
[data-brand="mb"] .btn--primary {
  background: var(--c-accent);
  border-color: var(--c-accent);
}
[data-brand="mb"] .btn--primary:hover {
  background: var(--c-accent-hover);
  border-color: var(--c-accent-hover);
}

/* --------------------------------------------------------------- loading */

@keyframes sqmb-spin { to { transform: rotate(360deg); } }

/* currentColor, not a fixed colour: dropped into a button via JS, it picks
   up whatever text colour that button variant already has (white on
   .btn--primary, accent-blue on .btn--light) with no per-variant mapping
   needed. Sized in em so it scales with the button's own font-size. */
.spinner {
  display: inline-block;
  width: 1em;
  height: 1em;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  flex-shrink: 0;
  animation: sqmb-spin .7s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  .spinner { animation-duration: 1.6s; }
}

.btn[aria-disabled="true"] { pointer-events: none; opacity: .75; }

/* A slim bar across the very top of the viewport while a real navigation
   (a link, or a form submit nothing here intercepts) is in flight. It never
   needs to reach 100% or reset itself — the page unloads before that
   matters, which clears it along with all other JS state for free. */
.nav-progress {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 9999;
  height: 3px;
  width: 0;
  background: linear-gradient(90deg, var(--c-accent), var(--c-accent-deep));
  opacity: 0;
  transition: width 4s cubic-bezier(.1, .6, .2, 1), opacity .2s ease;
}
.nav-progress.is-active { opacity: 1; width: 75%; }

/* ---------------------------------------------------------- hero slider */

/*
 * One slide is visible at a time and they cross-fade. Slides are stacked in a
 * grid cell rather than positioned absolutely, so the track keeps the height of
 * the tallest slide and the section never jumps as it rotates.
 */
.hero { padding-block: 10px 0; }

/*
 * The card is inset 10px inside the page container — 1270 wide against the
 * container's 1290 — so it sits on 85px margins at 1440.
 *
 * Its height is 70vh with a 600px floor, which is what the live pages use. It
 * has to stay viewport-relative: a fixed height changes where a `cover`
 * background lands, and being 30px out moves the photograph 15px.
 */
.hero__track {
  position: relative;
  display: grid;
  height: 70vh;
  min-height: 600px;
  margin-inline: 10px;
  border-radius: 28px;
  overflow: hidden;
  isolation: isolate;
}

.hero__slide {
  position: relative;
  grid-area: 1 / 1;
  display: grid;
  align-content: center;
  /* Spacing between the slide's parts is uneven on the live pages, so each
     part carries its own margin rather than sharing one gap. */
  gap: 0;
  /* 7% of the card, not a fixed inset — 89px at 1440, and it keeps tracking
     the card as it narrows. */
  padding: 20px 7%;
  color: #fff;
  background: var(--slide-image) center / cover no-repeat;
  opacity: 0;
  visibility: hidden;
  transition: opacity .6s ease, visibility .6s;
}
.hero__slide[aria-hidden="false"] { opacity: 1; visibility: visible; }

/* Legibility over photography. Flat 50% black, matching the live site. */
.hero__slide::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgb(0 0 0 / .5);
}
.hero__slide > * { position: relative; z-index: 1; }

/*
 * Light variant — a hero with no photograph behind it. MarketBuilder's hero is
 * this: dark type on the page background, no overlay, no rounded photo card.
 */
.hero__slide--light {
  min-height: 500px;
  color: var(--c-body);
  background: none;
}
.hero__slide--light::before { content: none; }
.hero__slide--light .hero__eyebrow { color: var(--c-accent); }
.hero__slide--light .hero__title { color: var(--c-ink-strong); }
.hero__slide--light .hero__body { color: var(--c-body); font-weight: 500; }
.hero__track:has(.hero__slide--light) { border-radius: 0; }

/* The slide's copy runs to 650px, not the full width of the card. */
.hero__slide > * { max-width: 650px; }

/* Poppins, like the heading under it — SQ's hero is the one place outside the
   footer where SupplyQuote leaves Jakarta. */
.hero__eyebrow { margin-bottom: 8px; font: 500 20px/28px var(--font-alt); color: #fff; }

.hero__title {
  margin-bottom: 22px;
  color: #fff;
  font: var(--t-h1);
  letter-spacing: var(--ls-h1);
}
/* The accent underline sits on the last words, as on the live site: a real
   3px border dropped 2px clear of the baseline, in its own brighter blue. */
.hero__title em {
  font-style: normal;
  padding-bottom: 2px;
  border-bottom: 3px solid #3d6aff;
}

/* Unitless (35/20 = 1.75 exactly, pixel-identical at desktop) so the
   17px mobile override at line ~235 doesn't strand a 35px desktop
   line-height on 3x the leading it needs. */
.hero__body { margin-bottom: 30px; font: 700 20px/1.75 var(--font); color: #f2f2f2; }

/* margin-top:0 is load-bearing — the row is a <p> following the body <p>, so
   the base `p + p` rule would push it down 16px. */
.hero__actions { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 0; }

/*
 * The hero's buttons are their own size and shape — wider padding, an 8px
 * radius and a brighter blue than the page buttons, which are 10px and the
 * deeper accent. Same markup, so they are overridden here rather than forked.
 */
.hero__actions .btn {
  padding: 15px 50px;
  line-height: 18px;
  border: 0;
  border-radius: 8px;
}
.hero__actions .btn--primary { background: #2563eb; }
.hero__actions .btn--ghost {
  padding: 14px 40px;
  border: 1px solid rgb(255 255 255 / .65);
  box-shadow: none;
}

/* Dots and arrows sit inside the card, over the photograph. */
.hero__dots {
  position: absolute;
  left: 0; right: 0; bottom: 22px;
  z-index: 2;
  display: flex;
  justify-content: center;
  gap: 10px;
}
.hero__dot {
  width: 12px; height: 12px;
  padding: 0;
  border-radius: 50%;
  background: #bfbfbf;
  transition: background-color .2s ease;
}
.hero__dot[aria-current="true"] { background: #fff; }

.hero__arrow {
  position: absolute;
  top: 50%;
  z-index: 2;
  display: grid;
  place-items: center;
  padding: 6px 10px;
  translate: 0 -50%;
  border-radius: 50%;
  color: #fff;
  font-size: 32px;
  line-height: 1;
  background: rgb(0 0 0 / .35);
  transition: background-color .2s ease;
}
.hero__arrow:hover { background: rgb(0 0 0 / .6); }
.hero__arrow--prev { left: 20px; }
.hero__arrow--next { right: 20px; }

@media (max-width: 640px) { .hero__arrow { display: none; } }

@media (max-width: 900px) {
  .hero__slide { min-height: 460px; padding: 48px 28px; }
  .hero__body { font-size: 17px; }
}

/* ----------------------------------------- split hero (MarketBuilder) */

/*
 * Copy on the left, video on the right. The columns and the gaps between them
 * are measured: 23 in from the container, 407 of text, a 37px gutter, then an
 * 810x459 video finishing 13px short of the container's right edge.
 */
.hero-split { padding-top: 34px; }

.hero-split__grid {
  display: grid;
  grid-template-columns: 407px 810px;
  column-gap: 37px;
  padding-inline: calc(var(--gutter) + 23px) calc(var(--gutter) + 13px);
  align-items: start;
}

/* The slides share one cell and cross-fade, so the column keeps the height of
   the tallest and nothing jumps as it rotates. */
.hero-split__slides { display: grid; margin-top: 20px; }

.hero-split__slide {
  grid-area: 1 / 1;
  align-self: start;
  opacity: 0;
  visibility: hidden;
  transition: opacity .6s ease, visibility .6s;
}
.hero-split__slide[aria-hidden="false"] { opacity: 1; visibility: visible; }

.hero-split__slide h2 {
  font: 600 46px/64.4px var(--font);
  letter-spacing: normal;
  color: var(--c-ink-strong);
}

/* A small blue label on its own line above the heading, inside it. block plus
   max-content so it takes a line of its own but only the width of its text.
   The 1px border is the whole of the pill's outline and all of the box it adds:
   with no horizontal padding the width is the text plus 2px, and 20 of line
   plus 15 of padding plus 2 of border is what makes it 37 tall rather than 35.
   It is also the one thing in the hero set in Poppins — the heading beside it
   stays on Jakarta — and Poppins runs wider, which is the rest of the 116 the
   clone measures against the 109 this was. */
.hero-split__badge {
  display: block;
  width: max-content;
  padding: 0 0 15px;
  font: 600 12px/20px var(--font-alt, var(--font));
  color: #3b57f9;
  background: #f5f7ff;
  border: 1px solid #3b57f9;
  border-radius: 20px;
}

.hero-split__slide p { margin-top: 30px; font-size: 16px; line-height: 24px; }
.hero-split__slide .btn { margin-top: 30px; }

.hero-split__media video {
  display: block;
  width: 100%;
  aspect-ratio: 810 / 459;
  background: #000;
}

/* ----------------------------------------------------------------- cards */

.cards {
  display: grid;
  gap: 24px;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

.card {
  padding: 30px;
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  border-radius: var(--radius);
}
/* No size here: every mark on the site has its own, and a width set in CSS
   overrides the width/height on the tag. */
.card img { object-fit: contain; }
.card h3 {
  margin-bottom: 10px;
  font: 600 20px/1.4 var(--font-alt, var(--font));
  letter-spacing: normal;
}

/* ------------------------------------------------------------- accordion */

.accordion { display: grid; gap: 12px; }

.accordion__item {
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  border-radius: var(--radius);
  overflow: hidden;
}

.accordion__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  width: 100%;
  padding: 20px 24px;
  text-align: left;
  font: 600 18px/1.5 var(--font);
  color: var(--c-ink);
}
.accordion__trigger::after {
  content: "";
  flex: 0 0 auto;
  width: 10px; height: 10px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform .2s ease;
}
.accordion__trigger[aria-expanded="true"]::after { transform: rotate(-135deg); }

/* Height is animated by the grid trick so no JS measurement is needed. */
.accordion__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .24s ease;
}
.accordion__panel[data-open="true"] { grid-template-rows: 1fr; }
.accordion__panel > div { overflow: hidden; }
.accordion__panel p { padding: 0 24px 22px; }

/* ----------------------------------------------------------------- media */

.media { border-radius: var(--radius); overflow: hidden; }
.media video, .media img { width: 100%; }

/* ------------------------------------------------------------ video player */

/* A poster-and-play-button stand-in for native browser controls: the clone
   hides its Plyr UI until hover, which plain `<video controls>` can't do, but
   dropping controls outright makes the video unplayable. Native `controls` is
   toggled on `play`/on hover-or-focus instead of styling `::-webkit-media-
   controls` — that's WebKit-only and would leave every other browser stuck
   with permanently visible controls or none at all. */
.video-player { position: relative; }
.video-player video { cursor: pointer; }

.video-player__play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 84px;
  height: 84px;
  padding: 0;
  border: 2px solid rgba(255, 255, 255, 0.85);
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.45);
  cursor: pointer;
  transition: background-color 0.2s, transform 0.2s, opacity 0.2s;
}
.video-player__play::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-46%, -50%);
  border-style: solid;
  border-width: 15px 0 15px 24px;
  border-color: transparent transparent transparent #fff;
}
.video-player__play:hover,
.video-player__play:focus-visible {
  background: var(--c-accent-deep);
  transform: scale(1.06);
}
.video-player.is-playing .video-player__play {
  opacity: 0;
  pointer-events: none;
}

/* Between clicking play and the video actually producing frames — the
   `waiting` event fires again on any later stall too, not just the first
   load, so this covers mid-playback buffering as well. Overrides
   .is-playing's opacity: 0 above (same specificity, later wins): the `play`
   event that triggers .is-playing fires as soon as playback is requested,
   which is well before `playing` says frames are actually rendering, so
   without this the button — and the spinner inside it — would vanish for
   the exact stretch it's meant to cover. */
.video-player.is-loading .video-player__play { opacity: 1; pointer-events: none; }
.video-player.is-loading .video-player__play::before { opacity: 0; }
.video-player.is-loading .video-player__play::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 28px;
  height: 28px;
  border: 3px solid #fff;
  border-right-color: transparent;
  border-radius: 50%;
  animation: sqmb-spin .7s linear infinite;
}

/* ------------------------------------------------------------- app gate */

/* A "coming soon" stand-in for CTAs that point at the SQ/MB web app, which
   isn't live yet. See SQMB_APP_READY in functions.php — once that flips to
   true this markup stops rendering and every gated link resumes working
   with no further change here. */

.app-gate[hidden] { display: none; }
.app-gate {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  padding: 20px;
}

.app-gate__backdrop {
  position: absolute;
  inset: 0;
  background: rgb(0 0 0 / .55);
}

.app-gate__panel {
  position: relative;
  width: 100%;
  max-width: 420px;
  padding: 40px 32px 32px;
  border-radius: var(--radius);
  background: var(--c-surface);
  text-align: center;
  box-shadow: 0 20px 60px rgb(0 0 0 / .25);
}

.app-gate__close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 32px;
  height: 32px;
  border: 0;
  border-radius: 50%;
  background: var(--c-surface-alt);
  color: var(--c-ink);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}
.app-gate__close:hover { background: var(--c-line); }

.app-gate__panel h2 {
  margin-bottom: 12px;
  font: 600 24px/1.3 var(--font-alt);
  color: var(--c-ink);
}

.app-gate__panel p {
  margin-bottom: 24px;
  font: 500 16px/24px var(--font);
  color: var(--c-body);
}

.app-gate__panel .btn { width: 100%; }
