/* ============================================================================
   Caelus landing page
   Phone first. Brand values come from tokens.css, a copy of brand/tokens.css;
   this file maps them onto scroll-craft's six roles and styles the page's own
   markup.
   ========================================================================== */
:root {
  --sc-canvas:     var(--caelus-cream);
  --sc-surface:    var(--caelus-tan);
  --sc-ink:        var(--caelus-black);
  --sc-ink-soft:   var(--caelus-ink-soft);
  --sc-accent:     var(--caelus-black);
  --sc-accent-ink: var(--caelus-cream-light);
  --sc-font-display: var(--caelus-font-display);
  --sc-font-text:    var(--caelus-font-text);
  --sc-display-weight: var(--caelus-display-weight);
  --sc-display-track:  var(--caelus-display-track);
  --sc-shadow-color: 25 45% 3%;
  /* scroll-craft rounds every focus ring by this, on the focused element itself
     (so a focused square button got round corners). BRAND.md: square corners. */
  --sc-r-sm: 0;

  --gutter: 22px;
  --bar-space: calc(86px + env(safe-area-inset-bottom));
  /* The page column on a computer: this wide at most, centred (used from 900 px). */
  --column: 75rem;
}

/* The footer carries the room under the pinned bar, so the page ends on its
   own ground rather than a strip of canvas. */
body { padding-bottom: 0; }

/* ------------------------------------------------------- shared pieces -- */
/* Ribbon label from the posters: a band with notched ends. Only the promos
   carry one. */
.ribbon { margin: 0; }
.ribbon span {
  display: inline-block;
  padding: 0.45rem 1.1rem;
  background: var(--caelus-black);
  color: var(--caelus-cream-light);
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: var(--caelus-label-track);
  text-transform: uppercase;
  clip-path: polygon(0 0, 100% 0, calc(100% - 8px) 50%, 100% 100%, 0 100%, 8px 50%);
}

/* ------------------------------------------------------- 1 · top screen -- */
.hero {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: calc(100svh - var(--bar-space));
  padding: 0;
}
.hero__top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  /* BRAND.md clear space: the gap between the badge and the name is a quarter
     of the badge's height. */
  --logo-size: 64px;
  gap: 0 calc(var(--logo-size) / 4);
  /* A phone: a small top padding, then the badge row and the menu row straight
     under it, so the menu costs the first screen no more than the old row did. */
  padding: 8px var(--gutter) 0;
}
/* The owners' bear badge, cut round so the cream shows around it. */
.logo { display: block; flex: none; width: var(--logo-size, 64px); height: var(--logo-size, 64px); }
/* The gym's name beside the badge: the wordmark, as BRAND.md has it: Onest
   bold in widely spaced capitals (not the headline font), quiet next to the
   headline. On a phone it takes two lines, CAELUS over JIU-JITSU. The wide
   letter spacing makes the gap between the two words clearly wider than the
   gaps between letters. */
.hero__name {
  margin: 0;
  min-width: 0;
  font-family: var(--sc-font-text);
  font-weight: 700;
  letter-spacing: 0.14em;
  font-size: 1rem;
  line-height: 1.2;
  /* With text at 200% the two lines are taller than the badge: this keeps
     the words off the menu row under them. Even above and below, so the
     words stay level with the badge and the menu links. */
  padding-block: 0.1em;
  text-transform: uppercase;
  color: var(--sc-ink);
}
.hero__name span { display: block; }

/* The small menu: four jumps, quieter than the pinned WhatsApp bar (small
   semibold Onest text in warm black, no fill, no box). It is not pinned: the
   bar already holds the bottom of a phone screen and stays the main action.
   On a phone it is a second row under the logo, each link a 44 px tall tap
   area, spread across the row, the first link's words on the page's left
   margin and the last link's words on its right margin (the row is 0.5rem
   wider than the margins on each side, which is the padding of those two
   links). The first row's right end holds the ID / EN switch (#47). With
   text at 200% the links wrap instead of overflowing. */
.menu {
  flex: 1 0 100%;
  /* Under the logo row on a phone, though it comes before the switch in the
     page's order (the switch follows it on a computer). */
  order: 1;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  margin-inline: -0.5rem;
}
.menu a {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding-inline: 0.5rem;
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.35;
  color: var(--sc-ink);
  text-decoration: none;
}
.menu a:hover, .menu a:focus-visible { text-decoration: underline; text-underline-offset: 0.2em; }
.menu a:focus-visible { outline: 2px solid var(--caelus-black); outline-offset: -2px; }

/* The ID / EN switch (#47): small Onest text, no fill, no box. The page's own
   language is warm black and bold, and not a link; the slash and the other
   language are soft ink and lighter, so the current one reads as current at a
   glance. The other language is a 44 px tap area, warm black and underlined on
   hover or focus, like the menu. On a phone it sits at the right end of the
   logo row, above the menu; on a computer after the menu, at the far right of
   the same row. 0.75rem each side of the slash, so the three parts read as one
   small group. The link's tap area runs past its letters on the outer side
   (20 px, in px so that it stays inside the 22 px page margin when text is
   enlarged; its padding there is taken back by an equal negative margin), so the
   letters of the last part still end on the margin. In the one-row layout
   (computers) the last link reaches inward instead (see that block). Where the row has no room (text at 200%), the switch
   drops to its own line, at the right. Not pinned. */
.lang-switch {
  flex: none;
  display: flex;
  align-items: center;
  margin: 0 0 0 auto;
  font-size: 0.9375rem;
  font-weight: 500;
  line-height: 1.35;
  color: var(--sc-ink-soft);
}
.lang-switch__current { font-weight: 700; color: var(--sc-ink); }
.lang-switch__link {
  display: flex;
  align-items: center;
  min-width: 44px;
  min-height: 44px;
  color: var(--sc-ink-soft);
  text-decoration: none;
}
.lang-switch > :first-child { padding: 0 0.75rem 0 0; }
.lang-switch > :last-child { padding: 0 0 0 0.75rem; }
.lang-switch > a:last-child { justify-content: flex-start; padding-right: 20px; margin-right: -20px; }
.lang-switch > a:first-child { justify-content: flex-end; padding-left: 20px; margin-left: -20px; }
.lang-switch__link:hover, .lang-switch__link:focus-visible { color: var(--sc-ink); text-decoration: underline; text-underline-offset: 0.2em; }
.lang-switch__link:focus-visible { outline: 2px solid var(--caelus-black); outline-offset: -2px; }
/* On a computer, and on a phone turned sideways (so a short screen does not
   lose 44 px to a second row): the name on one line, and the menu in the logo
   row at the right, wrapping under it if there is no room, and the ID / EN
   switch after it at the far right, set apart by a wider gap than the links'. */
@media (min-width: 900px), (orientation: landscape) and (max-height: 500px) {
  .hero__name span { display: inline; }
  .menu { flex: 0 1 auto; order: 0; margin: 0 0 0 auto; }
  .lang-switch { margin-left: 2.25rem; }
  /* In this row the page column ends at the last letters, so the last link's
     tap area reaches inward instead, over the slash, and nothing sticks out
     past the column's right edge. */
  .lang-switch > a:last-child { padding: 0 0 0 calc(0.75rem + 12px); margin: 0 0 0 -12px; }
  .menu a { padding-inline: 1.25rem; }
  .menu a:last-child { padding-right: 0; }
}

/* The group photo runs edge to edge in its own 3:2 shape, so no member at
   the edge is cut, and nothing sits on it. The top screen has no entrance:
   it shows at once. */
.hero__photo { margin: 0; background: var(--caelus-tan); }
.hero__photo img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1600 / 1066;
  object-fit: cover;
}

/* The cream band under the photo, the words and their button as one group.
   It grows to fill what is left of the screen above the pinned bar. */
.hero__band {
  flex: 1 0 auto;
  padding: 1.25rem var(--gutter) 1.5rem;
}

/* "No-gi jiu-jitsu" never breaks, so the headline turns after it: NO-GI
   JIU-JITSU, then IN BSD. NO-GI JIU-JITSU is 9.654em wide (9.594em measured in
   Unbounded 800 at -0.03em, plus the 0.06em added to the word gap), and the
   gutters leave 316 px at 360 px, so 9vw fits it there (313 px) and scales
   with the screen on phones. The tight tracking had left the gap between the
   words at 0.18em, narrower than the hyphen. The span is a block, so the
   heading is two lines at every width, and the real space before "in BSD"
   stays in the HTML so the heading still reads right. */
.hero__title {
  margin: 0;
  font-family: var(--sc-font-display);
  font-weight: var(--sc-display-weight);
  letter-spacing: var(--sc-display-track);
  font-size: clamp(min(2rem, 9vw), 9vw, 5.5rem);
  word-spacing: 0.06em;
  line-height: var(--caelus-display-lead);
  text-transform: uppercase;
}
.hero__turn { display: block; white-space: nowrap; }
.hero__note {
  margin: 0.6rem 0 0;
  font-size: 0.9375rem;
  font-weight: 500;
  line-height: 1.4;
  color: var(--sc-ink-soft);
  /* Never one word alone on the last line: at 1024 px the English line left
     "shorts" alone (#43), and on a 390 or 430 px phone the Indonesian one left
     "pendek" (#47). */
  text-wrap: pretty;
}
.hero__sub {
  margin: 1.1rem 0 0;
  font-size: 1.0625rem;
  line-height: 1.45;
  font-weight: 500;
  text-wrap: balance;
}
/* The warm black button under the offer, only as wide as its words, and the
   5.0 rating under it, both lined up on the left. */
.hero__actions {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  margin-top: 1.25rem;
}
/* The rating links to the listing, so a visitor can check it. Warm black on
   the cream band, 44 px tall to tap. The score is set in the headline font,
   and the words are lighter than the button's. */
.rating {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 44px;
  /* Keeps clear of the button's focus ring, which reaches 5 px below it. */
  margin-top: 0.375rem;
  color: var(--sc-ink);
  text-decoration: none;
}
.rating:focus-visible { outline: 2px solid var(--caelus-black); outline-offset: 3px; }
.rating__score {
  font-family: var(--sc-font-display);
  font-weight: var(--sc-display-weight);
  letter-spacing: var(--sc-display-track);
  font-size: 1.25rem;
  line-height: 1;
}
.rating__label {
  font-weight: 500;
  font-size: 0.9375rem;
  line-height: 1.4;
  /* Underlined, so the words read as a link, not bare text. The score is not. */
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
/* Where the jump lands, the Schedule frame's top line still shows above
   the heading. */
#schedule { scroll-margin-top: 4rem; }

/* A short phone screen (browser bars showing, a small phone): the logo row
   tightens, the rating moves up beside the button, and the photo gives up
   some height, trimmed top and bottom, so the button and the rating still
   clear the pinned bar. 17.9rem + 18vw is the tightened logo row and the
   band under the photo, measured at 360 to 430 px: 17.9rem for the logo row,
   the padding, the small line, the offer, the button row and the bottom
   padding, and 18vw for the headline's two lines (a font of 9vw with a line
   height of 1, so 2 x 9vw). The photo never drops below 55% of the width.
   The button and rating row never wraps: the rating keeps its size, and the
   button's own words wrap to two lines if there is no room. */
@media (max-width: 899px) and (max-height: 760px) {
  /* The badge and the name shrink with it, which gives back the 16 px the
     bigger badge costs. */
  .hero__top { --logo-size: 48px; }
  .hero__photo img {
    max-height: max(55vw, calc(100svh - var(--bar-space) - 17.9rem - 18vw));
    object-position: 50% 35%;
  }
  .hero__band { padding-top: 1rem; }
  .hero__actions { flex-direction: row; flex-wrap: nowrap; align-items: center; column-gap: 0.5rem; }
  .hero__actions .hero__go { padding-inline: 1rem; min-width: 0; }
  .hero__actions .rating { margin-top: 0; flex: none; white-space: nowrap; }
  /* The Indonesian small line ("No-gi artinya ...") takes two lines on every
     phone, and no wording of it fits one, so its page keeps room for that
     second line (1.3125rem, the line's height) and its photo may go down to
     half the width. The English page is unchanged. (:where keeps it no
     stronger than the sideways-phone rule further down, which still wins.) */
  :where(.hero__photo) img:lang(id) {
    max-height: max(50vw, calc(100svh - var(--bar-space) - 17.9rem - 1.3125rem - 18vw));
  }
}

/* ------------------------------------------------------ 2 · why caelus -- */
.cut {
  display: flex;
  min-height: 72svh;
  padding: 4.5rem var(--gutter);
  background: var(--cut-ground);
  color: var(--sc-ink);
}
.cut__inner { width: 100%; max-width: 72rem; margin-inline: auto; }
.cut .sc-stack > :is(h2, h3) { margin-top: var(--sc-5); }
.cut .sc-stack > :is(h2, h3):first-child { margin-top: 0; }
.cut .sc-stack > .cut__body { margin-top: 1.25rem; }

/* Each cut lands on its own ground with a hard edge, and anchors its copy
   differently: bottom, middle, top. */
.cut--dark {
  --cut-ground: var(--caelus-charcoal);
  --sc-ink: var(--caelus-cream);
  --sc-ink-soft: var(--caelus-ink-soft-dark);
  --sc-accent: var(--caelus-cream);
  --sc-accent-ink: var(--caelus-charcoal);
  align-items: flex-end;
}
.cut--black { --cut-ground: var(--caelus-black); }
.cut--tan   { --cut-ground: var(--caelus-tan); align-items: center; }
.cut--cream { --cut-ground: var(--caelus-cream); align-items: flex-start; }
/* The ground never moves the words: the practical sections and Find us keep their
   copy at the top, whichever of cream or tan they sit on. */
.cut--practical, .cut--tan.row { align-items: flex-start; }

.cut__title {
  font-family: var(--sc-font-display);
  font-weight: var(--sc-display-weight);
  letter-spacing: var(--sc-display-track);
  font-size: clamp(min(2rem, 10vw), 10vw, 5rem);
  line-height: var(--caelus-display-lead);
  text-transform: uppercase;
  margin: 0;
}
.cut__body {
  max-width: 30ch;
  margin: 0;
  font-size: 1.0625rem;
  line-height: 1.55;
  color: var(--sc-ink-soft);
  text-wrap: pretty;
}

.reasons {
  list-style: none;
  display: grid;
  gap: 0.5rem;
  margin: 1.25rem 0 0;
  padding: 0;
  font-size: 1.0625rem;
  line-height: 1.4;
  color: var(--sc-ink-soft);
}
.reasons li { text-wrap: balance; }
.reasons strong { font-weight: 700; color: var(--sc-ink); }
.row__text > .quote { margin-top: 2rem; }

/* A text-and-photo row. On a phone the picture runs edge to edge straight
   under the section above, with the words below it on the section's ground.
   Side by side on desktop, picture wider. */
.row { min-height: 0; padding: 0; }
.row__photo { margin: 0; aspect-ratio: 978 / 652; background: var(--caelus-tan); color: var(--caelus-black); }
.row__photo img { display: block; width: 100%; height: auto; }
/* Find us: the Caelus sign, 4 to 3, never shown wider than 640 px, under its
   1200 px file. Up to 640 px it runs edge to edge like the flag photo. Past
   that it lines up with the words instead of the screen's edge. On desktop
   the row's own side padding does that, so it takes no margin of its own. */
.row__photo--sign { aspect-ratio: 4 / 3; max-width: 40rem; }
@media (min-width: 641px) and (max-width: 899px) {
  .row__photo--sign { margin-inline: var(--gutter); }
}
.row__text { padding: 2.25rem var(--gutter) 3.5rem; }

/* ------------------------------------------- shared, sections 3 to 11 -- */
.sr-only {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

/* Practical sections run as long as their facts, not a set height. */
.cut--practical { min-height: 0; padding-block: 4rem; }
/* With large text the headline grows with it, so it stays bigger than the
   words under it. At normal text sizes 8.5vw always wins. */
.cut__title--md { font-size: clamp(min(1.75rem, 8.5vw), max(8.5vw, 1.25rem), 3.75rem); }
.cut--practical .cut__title--md { margin-bottom: 1.25rem; }
/* The no-gi line under the Classes headline: body text at a readable measure, not the 30ch of the short lines. */
.classes__intro { max-width: 60ch; }
.nowrap { white-space: nowrap; }

.cut--dark { color: var(--sc-ink); }

.cut a:not(.cta, .btn) {
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}
.cut a:not(.cta, .btn):focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }
/* Text links get a 44 px tall tap area. The padding is taken back with a
   negative margin, so the lines sit exactly where they did. */
.more a,
.faq details > p a { display: inline-block; padding-block: 10px; margin-block: -10px; }

/* --------------------------------------------------------- 3 · classes -- */
/* Three panels with no card around them. On a phone each photo runs edge to
   edge up to 464 px wide. Each photo's space is held, so nothing moves when it
   arrives. */
.panels { list-style: none; display: grid; gap: 3rem; margin: 1.75rem 0 0; padding: 0; }
.panel { display: flex; flex-direction: column; }
.panel__photo {
  margin: 0 calc(-1 * var(--gutter));
  aspect-ratio: 4 / 3;
  background: var(--caelus-tan);
  color: var(--caelus-black);
}
.panel__photo img { display: block; width: 100%; height: auto; }
.panel__text { display: flex; flex: 1; flex-direction: column; padding-top: 1.25rem; }
.panel__name {
  margin: 0;
  font-family: var(--sc-font-display);
  font-weight: var(--sc-display-weight);
  letter-spacing: var(--sc-display-track);
  font-size: 1.375rem;
  line-height: 1.1;
  text-transform: uppercase;
}
.panel__words {
  max-width: 34ch;
  margin: 0.6rem 0 1.25rem;
  font-size: 1.0625rem;
  line-height: 1.6;
  color: var(--sc-ink-soft);
  text-wrap: pretty;
}
/* Pushed to the foot, so the buttons line up when the panels stand side by side. */
.panel__go { width: 100%; margin-top: auto; }

/* Wider than 464 px: the photos stop there. All three files are 960 px wide
   since #74; whether the panels grow on desktop belongs to #43. */
@media (min-width: 465px) {
  .panel__photo { margin-inline: 0; max-width: 464px; }
}
/* Still stacked: the words and button stop there too, so the right edges meet. */
@media (min-width: 465px) and (max-width: 599px) {
  .panel { max-width: 464px; }
}
/* A tablet: the words sit beside the photo, so no half of the screen is empty. */
@media (min-width: 600px) and (max-width: 899px) {
  .panel { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 1.5rem; }
  .panel__text { padding-top: 0; }
}

/* ---------------------------------------------- 4 · your first class -- */
.cut--first { align-items: center; padding-block: 3.5rem 4.5rem; }
/* Two lines at every width. Only the screen width sets the size, so the lines
   still fit with text at 200%. */
.cut--first .cut__title { font-size: min(max(9.15vw, 1.125rem), 3.75rem); } /* grows with large text, so it stays bigger than the words under it */

/* The real message, as a sent chat bubble: on the right, with a tail at its
   top corner. Square corners and solid colour, like the rest of the page. */
.chat { margin-top: 2rem; max-width: 34rem; }
.chat__lead { margin: 0; font-size: 1.0625rem; line-height: 1.55; }
/* "Tap" on a phone, "Use" on a computer (see the desktop block). Only the one
   that shows is read out. */
.on-desktop { display: none; }
.chat__bubble {
  position: relative;
  margin: 1rem 0.875rem 0 auto;
  width: fit-content;
  max-width: 86%;
  padding: 0.875rem 1.125rem;
  background: var(--caelus-black);
  color: var(--caelus-cream-light);
  font-size: 1.0625rem;
  font-weight: 500;
  line-height: 1.5;
}
.chat__bubble::after {
  content: "";
  position: absolute;
  top: 0;
  left: 100%;
  width: 0.875rem;
  height: 1rem;
  background: var(--caelus-black);
  clip-path: polygon(0 0, 100% 0, 0 100%);
}
.chat__means { margin: 1rem 0 0; font-size: 1rem; line-height: 1.5; color: var(--sc-ink-soft); text-wrap: pretty; }

.first-note { margin-top: 2.5rem; max-width: 34rem; }
.first-note__title {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 700;
}
.first-note__text { margin: 0.5rem 0 0; font-size: 1.0625rem; line-height: 1.55; color: var(--sc-ink-soft); text-wrap: pretty; }

/* -------------------------------------------------------- 5 · schedule -- */
/* The posters' double frame, around the timetable and the price list. */
.framed { position: relative; padding: 2.25rem 1.25rem 2rem; }
.framed__lines,
.framed__lines::after {
  position: absolute;
  border: var(--caelus-frame-line) solid var(--caelus-black);
  pointer-events: none;
}
.framed__lines { inset: 0; }
.framed__lines::after { content: ""; inset: var(--caelus-frame-gap); }

.timetable { width: 100%; border-collapse: collapse; }
.timetable th, .timetable td {
  padding: 0.8rem 0;
  border-top: 1px solid color-mix(in oklab, var(--sc-ink) 16%, transparent);
  text-align: left;
  vertical-align: top;
}
.timetable th {
  width: 42%;
  font-size: 1rem;
  font-weight: 700;
  padding-top: 1rem;
}
.schedule__note { margin: 0 0 1rem; font-size: 0.9375rem; line-height: 1.5; color: var(--caelus-ink-soft); text-wrap: pretty; }
.timetable th { width: 37%; padding-right: 0.75rem; }
.timetable th, .timetable td { padding-block: 0.6rem; }
.timetable th { padding-top: 0.8rem; }
.timetable td { font-size: 1rem; line-height: 1.5; }
.class { display: block; padding-left: 3.66em; text-indent: -3.66em; } /* 3.4em time + one space, so a wrapped line sits under the label */
.class + .class { margin-top: 0.3rem; }
.class b { display: inline-block; min-width: 3.4em; font-weight: 700; font-variant-numeric: tabular-nums; text-indent: 0; }

/* With large text the day and its classes no longer fit side by side, so
   the day goes above its classes. At normal text sizes the frame is wider
   than 16rem and this never applies. */
.framed { container-type: inline-size; }
@container (max-width: 16rem) {
  .timetable tr, .timetable th, .timetable td { display: block; width: auto; }
  .timetable th { padding-right: 0; padding-bottom: 0; }
  .timetable td { border-top: 0; padding-top: 0.3rem; }
  .class { padding-left: 0; text-indent: 0; }
}

/* ------------------------------------------------ 6 · prices and promos -- */
.pricelist { margin-top: 1.5rem; max-width: 30rem; }
.pricelist dl { margin: 0; }
.pricelist__group {
  margin: 1.75rem 0 0.25rem;
  font-size: 1rem;
  font-weight: 700;
  color: var(--sc-ink);
}
.pricelist__group:first-child { margin-top: 0; }
.pricelist > div + div { margin-top: 1.75rem; }
/* "Ask about a plan": the full width of the list on a phone, so it is easy to hit. */
.prices__go { width: 100%; max-width: 30rem; margin-top: 1.75rem; }
.pricelist__row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.75rem;
  padding: 0.65rem 0;
  border-bottom: 1px solid color-mix(in oklab, var(--sc-ink) 18%, transparent);
}
/* The name takes the room left beside the price, so a long note wraps under it instead of pushing the price down. Balanced, so a name that wraps ("Unlimited, 1 month" at 360 px) does not strand "1" at the line end. */
.pricelist__row dt { font-size: 1rem; font-weight: 500; flex: 1 1 0; text-wrap: balance; }
/* The small line under a longer plan's name: what the plan gives, per month. */
.pricelist__note {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.9375rem;
  font-weight: 400;
  line-height: 1.35;
  color: var(--sc-ink-soft);
}
.pricelist__row dd {
  margin: 0 0 0 auto;
  font-family: var(--sc-font-display);
  font-weight: var(--sc-display-weight);
  letter-spacing: var(--sc-display-track);
  font-size: 1.5rem;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.promos { display: grid; gap: 2.5rem; }
.promo .ribbon { margin-bottom: 1rem; }
.promo__line { margin: 0.35rem 0 0; font-size: 1rem; line-height: 1.55; color: var(--caelus-black); max-width: 32ch; text-wrap: pretty; }
.promo__big {
  margin: 0;
  font-family: var(--sc-font-display);
  font-weight: var(--sc-display-weight);
  letter-spacing: var(--sc-display-track);
  font-size: 3.25rem;
  line-height: 1;
  text-transform: uppercase;
}
/* The Indonesian big line, "Diskon 20%", has one long word: with text at
   200% DISKON alone is wider than a phone. There it is never more than 20%
   of the promo's width per letter size (DISKON is 4.8 em wide), which at
   normal text size is always more than 3.25rem, so only enlarged text
   shrinks. The English "20% off" breaks into short words and is unchanged. */
.promo:lang(id) { container-type: inline-size; }
.promo__big:lang(id) { font-size: min(3.25rem, 20cqi); }

/* ----------------------------------------------------- 8 · on the mats -- */
/* A phone: the big clip edge to edge, the two small clips under it, the long
   photo under them. Each box has its file's shape, so nothing is cropped or
   stretched, and its space is held before anything arrives. */
.mats {
  --mats-gap: 6px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--mats-gap);
  margin: 1.75rem calc(-1 * var(--gutter)) 0;
}
.mats__media {
  display: block;
  width: 100%;
  height: auto;
  object-fit: cover;
  background: var(--caelus-tan);
}
.mats__big { grid-column: 1 / -1; aspect-ratio: 4 / 5; }
.mats__small { aspect-ratio: 1; }
.mats__photo { grid-column: 1 / -1; aspect-ratio: 16 / 9; }
/* 992 px keeps the big clip about 607 px wide, under its 720 px file, and the
   small clips about 373 px, under their 576 px files. */
.cut__inner--mats { max-width: 992px; }
/* From 600 px: the big clip on the wider side, the small clips stacked beside
   it. The first column is worked out so the two squares and the gap between
   them come out exactly as tall as the 4:5 clip. */
@media (min-width: 600px) {
  .mats {
    --mats-gap: 12px;
    grid-template-columns: calc((100% - var(--mats-gap) / 2) / 1.625) 1fr;
    margin-inline: 0;
  }
  .mats__big { grid-column: 1; grid-row: span 2; }
}
/* Playing clips pause on a tap (see the clip script in index.html). */
.mats video[role="button"] { cursor: pointer; }
/* Drawn inside the clip: on a phone the clips reach the screen's edge, where an
   outer outline would be cut off. */
.mats video:focus-visible { outline: 3px solid var(--caelus-black); outline-offset: -3px; }
.more { margin: 1.5rem 0 0; font-weight: 600; font-size: 0.9375rem; }

/* --------------------------------------------------------- 8b · reviews -- */
.quotes { list-style: none; margin: 1.75rem 0 0; padding: 0; display: grid; gap: 2.25rem; }
.quote { max-width: 34rem; }
.quote__text { margin: 0; }
.quote__text p { margin: 0; font-size: 1.0625rem; line-height: 1.6; text-wrap: pretty; }
.quote__by {
  margin: 0.9rem 0 0;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--sc-ink-soft);
}
/* The Google button sits on its own line under the quotes. */
.reviews__go { margin-top: 1.75rem; }

/* ------------------------------------------------------- 9 · questions -- */
.faq { display: grid; gap: 2.25rem; max-width: 44rem; margin-top: 2.25rem; }
/* The small heading over each group: Onest like every label, a step above the
   question rows, in sentence case. */
.faq__title { margin: 0 0 0.25rem; font-size: 1.25rem; font-weight: 700; line-height: 1.3; }
.faq summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  min-height: 3.5rem;
  padding: 0.9rem 0;
  font-weight: 600;
  font-size: 1.0625rem;
  line-height: 1.4;
  cursor: pointer;
  list-style: none;
  scroll-margin-bottom: 7rem; /* a question reached by keyboard stops clear of the pinned bar */
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+";
  flex: none;
  font-weight: 400;
  font-size: 1.75rem;
  line-height: 1;
  margin-right: 0.15em; /* room for the turned sign at 200% text */
  transition: transform 160ms var(--sc-ease-out);
}
.faq details[open] summary::after { transform: rotate(45deg); }
.faq summary:focus-visible { outline: 2px solid var(--caelus-black); outline-offset: 2px; }
.faq details > p { margin: -0.35rem 0 1.25rem; max-width: 40ch; font-size: 1rem; line-height: 1.6; text-wrap: pretty; }

/* --------------------------------------------------------- 6 · find us -- */
.address { margin-top: 1.25rem; font-style: normal; font-size: 1.0625rem; line-height: 1.6; }
.address strong { font-weight: 700; }
.address__phone, .address__near { margin-top: 0.75rem; font-size: 1.0625rem; line-height: 1.6; }
.address__phone { white-space: nowrap; }
.address__near { text-wrap: pretty; }
.parking { font-size: 1.0625rem; line-height: 1.6; font-weight: 600; text-wrap: pretty; }
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0.5rem 1.4rem;
  background: var(--caelus-black);
  color: var(--caelus-cream-light);
  font-weight: 700;
  font-size: 0.9375rem;
  text-align: center;
  text-decoration: none;
  transition: background-color 140ms var(--sc-ease-out), transform 120ms var(--sc-ease-out);
}
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: 2px solid var(--caelus-black); outline-offset: 3px; }
@media (hover: hover) and (pointer: fine) {
  .btn:hover { text-decoration: underline; text-underline-offset: 0.2em; }
}
/* A WhatsApp button in the page: brown, the page's one accent. */
.btn--wa { background: var(--caelus-brown); }

/* Today's row in the schedule, marked by today.js:
   a black bar down the left of the day, and a small tag under its name. */
tr.is-today > th {
  padding-left: 0.75rem;
  border-left: 4px solid var(--caelus-black);
}
.today-tag {
  display: block;
  width: max-content;
  margin-top: 0.4rem;
  padding: 0.15rem 0.45rem;
  background: var(--caelus-black);
  color: var(--caelus-cream-light);
  font-size: 0.8125rem;
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: var(--caelus-label-track);
  text-transform: uppercase;
}
/* With large text the day sits above its classes, so the bar runs down
   both. */
@container (max-width: 16rem) {
  .timetable tr.is-today > td {
    padding-left: 0.75rem;
    border-left: 4px solid var(--caelus-black);
  }
}

/* ---------------------------------------------------------- 11 · close -- */
.cut--close { min-height: 75svh; align-items: center; }
.cut--close .cut__body { margin-top: 1.25rem; }
/* "No experience needed." moves to its own line whole, but wraps inside the
   screen when text is set very large (a plain nowrap pushed the page sideways). */
.cut--close .nowrap { display: inline-block; max-width: 100%; white-space: normal; }
/* Below the desktop breakpoint the closing headline takes the section-headline size, so "class is free"
   stays on one line. Desktop keeps the larger size. This clamp must match .cut__title--md's: keep both in step. */
@media (max-width: 899px) {
  .cut--close .cut__title { font-size: clamp(min(1.75rem, 8.5vw), max(8.5vw, 1.25rem), 3.75rem); }
}
.cut .cta--close {
  display: inline-flex;
  width: auto;
  max-width: none;
  min-height: 60px;
  margin: 2rem 0 0;
  padding: 0.5rem 1.75rem;
  font-size: 1.0625rem;
  text-align: left;
  justify-content: flex-start;
}

.foot {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.75rem;
  padding: 2rem var(--gutter) calc(2rem + var(--bar-space));
  background: var(--caelus-black);
  color: var(--caelus-cream);
}
.foot .logo { width: 5.5rem; height: 5.5rem; }
/* The gym's details, at body size (1rem, a little under Find us's 1.0625rem)
   in the soft colour. The
   number is plain words: WhatsApp stays the one action. */
.foot__address, .foot__phone { margin: 0; font-style: normal; font-size: 1rem; line-height: 1.6; color: var(--caelus-ink-soft-dark); }
.foot__address strong { font-weight: 700; }
.foot__phone { white-space: nowrap; }
/* A 44 px tall tap area. */
.foot__ig {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  font-size: 1rem;
  font-weight: 600;
  color: var(--caelus-ink-soft-dark);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}
.foot__ig:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }
.foot__motto {
  margin: 0;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: var(--caelus-label-track);
  text-transform: uppercase;
  color: var(--caelus-ink-soft-dark);
}

/* ------------------------------------------- the pinned WhatsApp bar -- */
.bar {
  position: fixed;
  inset: auto 0 0 0;
  z-index: var(--sc-z-chrome);
  padding: 0 14px calc(12px + env(safe-area-inset-bottom));
  background: var(--caelus-charcoal);
}

/* A white belt across the top edge, black rank bar near the end. */
.belt {
  position: relative;
  height: 10px;
  margin: 0 -14px 12px;
  background: var(--caelus-cream-light);
}
.belt::before {
  content: "";
  position: absolute;
  inset: 2px 0;
  border-block: 1px solid color-mix(in oklab, var(--caelus-tan) 70%, transparent);
}
.belt__rank {
  position: absolute;
  top: 0; bottom: 0; right: 28px;
  display: flex;
  gap: 6px;
  padding: 0 9px;
  background: var(--caelus-black);
}
.belt__stripe {
  width: 4px;
  background: var(--caelus-cream-light);
  transform: scaleY(0);
  transform-origin: 50% 0;
  transition: transform 260ms var(--sc-ease-out);
}
.belt__stripe.is-earned { transform: scaleY(1); }

.cta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  width: 100%;
  max-width: 28rem;
  min-height: 52px;
  margin-inline: auto;
  padding: 0.5rem 1.25rem;
  background: var(--caelus-cream);
  color: var(--caelus-black);
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: 0.01em;
  text-align: center;
  text-decoration: none;
  transition: background-color 140ms var(--sc-ease-out), transform 120ms var(--sc-ease-out);
}
.cta__icon { width: 20px; height: 20px; flex: none; }
.cta:active { transform: translateY(1px); }
.cta:focus-visible { outline: 2px solid var(--caelus-cream-light); outline-offset: 3px; }
@media (hover: hover) and (pointer: fine) {
  .cta:hover { background: var(--caelus-cream-light); }
}

/* --------------------------------------------------------------- motion -- */
/* Only headlines and pictures carry [data-sc-in]; tables, body text and buttons
   are simply there. The script after scroll-craft sets html.motion unless reduced
   motion is on. Without it (reduced motion, scripts off, or scroll-craft late or
   failed) the page shows settled, whatever scroll-craft's own styles say. Each
   reveal runs once and is over within 600 ms; page check 56 reads the times. The
   transition sits on .sc-in, so setting html.motion hides things at once. */
:root { --ease-settle: cubic-bezier(0.2, 0.7, 0.1, 1); }
html:not(.motion) [data-sc-in] { opacity: 1; transform: none; transition: none; }

/* A jump to a section lands at once: the browser's smooth scroll takes about a
   second down this long page. */
html { scroll-behavior: auto; }

/* A picture settles in. */
.motion [data-sc-in] { transform: scale(0.98); transition: none; }
.motion [data-sc-in].sc-in {
  opacity: 1;
  transform: none;
  transition: opacity 320ms var(--sc-ease-out), transform 520ms var(--ease-settle);
}
/* A headline rises a short way. */
.motion .cut__title[data-sc-in] { transform: translate3d(0, 0.32em, 0); }
.motion .cut__title[data-sc-in].sc-in {
  transform: none;
  transition: opacity 240ms var(--sc-ease-out), transform 440ms var(--ease-settle);
}

/* ------------------------------------------------------ reduced motion -- */
@media (prefers-reduced-motion: reduce) {
  .belt__stripe, .faq summary::after, .btn, .cta { transition: none; }
}

/* ------------------------------------------------------------- desktop -- */
@media (min-width: 900px) {
  :root { --gutter: 48px; }

  /* The band on the left, the wider photo on the right. On a computer the top
     screen reaches the pinned bar (see the computer-only block below). */
  .hero {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    grid-template-rows: auto auto;
    column-gap: 4rem;
    min-height: 0;
    /* In the page column: 1200 px at most, centred; the gutter when the screen is narrower. */
    padding: 0 max(var(--gutter), calc((100% - var(--column)) / 2)) 4rem;
  }
  .hero__top { grid-column: 1 / -1; padding: 1.5rem 0; }
  .hero__name { font-size: 1.125rem; }
  .hero__photo {
    grid-column: 2;
    grid-row: 2;
    align-self: end;
    justify-self: end;
    width: auto;
    max-width: 100%;
    max-height: calc(100svh - var(--bar-space) - 9.5rem);
  }
  .hero__photo img { width: auto; max-width: 100%; max-height: inherit; }
  /* The headline is sized to the band's own width: NO-GI JIU-JITSU is
     9.654em wide, so 10.3cqi (10.3% of the band) always keeps it whole. */
  .hero__band { grid-column: 1; grid-row: 2; align-self: end; padding: 0; container-type: inline-size; }
  .hero__title { font-size: min(5.5rem, 10.3cqi); }
  .hero__note { font-size: 1.125rem; }
  .hero__sub { font-size: 1.25rem; }
  #schedule { scroll-margin-top: 6rem; }

  .cut { padding-block: 7rem; }
  /* One page column for every section: --column (75rem, 1200 px) at most,
     centred. Narrower blocks below (the schedule frame, On the mats) sit
     centred inside it. */
  .cut__inner { max-width: var(--column); }
  .foot { padding-inline: max(var(--gutter), calc((100% - var(--column)) / 2)); }
  .cut__body { font-size: 1.1875rem; }

  /* The row: the photo on the wider side of the uneven grid. The headline is
     sized to the words' own width, so its longest line always stays whole. */
  .row { padding: 6rem var(--gutter); }
  .row .cut__inner {
    display: grid;
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    column-gap: 4rem;
    align-items: center;
  }
  .row__text { padding: 0; container-type: inline-size; }
  .row__text .cut__title { font-size: min(3.75rem, 11.5cqi); }
  /* Find us: the sign on the wide side at the left, the words beside it, still
     4 to 3. No cap of its own: its cell (7fr of the column, about 663 px at
     most) keeps it well under its 1200 px file. */
  .row__photo--sign { max-width: none; }
  .reasons { font-size: 1.1875rem; }

  .cut--practical { padding-block: 6rem; }
  .promos { grid-template-columns: 1fr 1fr; gap: 4rem; }
  /* The second row takes the extra height of the longer plans' notes, so Kids class does not move down. */
  .pricelist { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: auto 1fr; gap: 1.75rem 3rem; max-width: none; }
  .pricelist > div + div { margin-top: 0; }
  /* On a wide screen the button keeps its own width at the foot of the list. */
  .prices__go { width: auto; }
  /* Monthly and Longer plans run two rows deep, so Kids class sits under Pay as you go. */
  .pricelist > div:nth-child(2),
  .pricelist > div:nth-child(3) { grid-row: span 2; }

  /* Classes: the three panels side by side. Each column stays under 464 px
     (see the 465 px rule above). */
  .panels { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 2rem; margin-top: 2.5rem; }
  .panel__name { font-size: 1.5rem; }

  /* Your first class and Questions: the headline on the narrow left, the rest
     on the wide right, on the 5-to-7 grid. The headline is sized to its own
     column (100cqi is the page column, 4rem the gap), so its longest line stays
     whole; --title-fit is how much of the column the longest line may fill. */
  .cut--first .cut__inner,
  .cut--questions .cut__inner {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    column-gap: 4rem;
    align-items: start;
    container-type: inline-size;
  }
  .cut--first .cut__title,
  .cut--questions .cut__title {
    font-size: min(3.75rem, calc((100cqi - 4rem) * 5 / 12 * var(--title-fit)));
    margin-bottom: 0;
  }
  .cut--first { --title-fit: 0.1; }
  .cut--questions { --title-fit: 0.115; }
  /* Your first class runs as long as its words, with the same room above and
     below as Why Caelus and Find us (#44: the 72svh height left about 220 px of
     empty tan above and below at 1440). */
  .cut--first { min-height: 0; padding-block: 6rem; }

  /* Reviews (#44): the headline on the narrow left, the two quotes stacked on
     the wide right and the button under both, on the same 5-to-7 grid as
     Questions, the headline sized to its column the same way. */
  .cut__inner:has(> .quotes) {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    grid-template-rows: auto 1fr;
    column-gap: 4rem;
    align-items: start;
    container-type: inline-size;
    --title-fit: 0.1;
  }
  .cut__inner:has(> .quotes) > .cut__title {
    grid-column: 1;
    grid-row: 1 / span 2;
    font-size: min(3.75rem, calc((100cqi - 4rem) * 5 / 12 * var(--title-fit)));
  }
  .quotes { grid-column: 2; margin-top: 0; }
  /* The quotes fill the wide column to its edge, like the questions. */
  .quotes .quote { max-width: none; }
  .reviews__go { grid-column: 2; justify-self: start; }

  /* Your first class: the note goes under the headline, and the chat, level
     with the headline, is as tall as both. */
  .cut--first .cut__inner { grid-template-rows: auto 1fr; }
  .cut--first .cut__inner > .sc-stack { grid-column: 1; grid-row: 1; }
  .chat { grid-column: 2; grid-row: 1 / span 2; margin-top: 0; max-width: none; }
  .first-note { grid-column: 1; grid-row: 2; }

  .faq { max-width: none; margin-top: 0; }

  /* The schedule frame is narrow, so each day sits close to its times, and
     sits in the middle of the column. */
  .timetable th { width: 8.5rem; }

  .framed { padding: 3.5rem 3rem 3rem; max-width: 44rem; }
  /* The price list's three columns need the full width, so each price stays
     beside its plan. Its frame runs the whole page column, so its edges line
     up with the sections above and below (a 72rem cap left it 24 px inside). */
  .framed:has(.pricelist) { max-width: var(--column); }

  /* The closing headline grows to fill more of the column's open right side
     (#44), still two lines. */
  .cut--close .cut__title { font-size: min(6.75rem, 9vw); }

  /* On the mats is narrowed a little and centred in the column. The big clip
     comes out about 548 px wide, under its 720 px file. */
  .cut__inner--mats { max-width: 56rem; }
}

/* A small laptop: the price list's columns are narrow, so a longer plan's
   price goes under its note, on the right, and the note keeps the column's
   width (#44: beside the price it took 4 lines in English at 950 to 1050). */
@media (min-width: 900px) and (max-width: 1199px) {
  .pricelist__row:has(.pricelist__note) dd { flex-basis: 100%; text-align: right; }
}

/* Things that are for a computer only, not for a phone held sideways (which
   can be 900 px wide or more but is under 501 px tall). The pinned bar is
   slimmer: 68 px tall in all (the belt 8, the button 44, and 8 above and below
   the button) against 86 on a phone. The first class line says "Use" on a
   computer and "Tap" on a phone. */
@media (min-width: 900px) and (min-height: 501px) {
  .on-phone { display: none; }
  /* A block, so the line spans the chat's column as the paragraph does (it is
     the paragraph's only shown part, so the words wrap the same). The
     Indonesian page has no line under the bubble, and without this its right
     side would end at the bubble, short of the column by the tail's width. */
  .on-desktop { display: block; }
  :root { --bar-space: calc(68px + env(safe-area-inset-bottom)); }
  .bar { padding-bottom: calc(8px + env(safe-area-inset-bottom)); }
  .belt { height: 8px; margin-bottom: 8px; }
  .cta { min-height: 44px; padding-block: 0.25rem; }
  /* The top screen reaches down to the pinned bar, so the bar never slices
     the next section's headline on load (#44); the band and the photo sit in
     the middle of the room under the logo row, the cream split evenly above
     and below them (the bottom padding matches the logo row's 1.5rem). */
  .hero { min-height: calc(100svh - var(--bar-space)); grid-template-rows: auto 1fr; padding-bottom: 1.5rem; }
  .hero__photo, .hero__band { align-self: center; }
}

/* A phone turned sideways, of any width: the band and the photo sit side by
   side with a smaller badge and headline, so the headline and the button
   show above the pinned bar. Last, so it wins over the desktop layout. */
@media (orientation: landscape) and (max-height: 500px) {
  .hero {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-rows: auto auto;
    column-gap: 1.5rem;
    min-height: 0;
    padding: 0 var(--gutter) 1.5rem;
  }
  .hero__top { grid-column: 1 / -1; padding: 8px 0; --logo-size: 48px; }
  .hero__photo { grid-column: 2; grid-row: 2; align-self: start; justify-self: auto; max-height: none; }
  .hero__photo img { width: auto; max-width: 40vw; max-height: calc(100svh - var(--bar-space) - 5rem); }
  .hero__band { grid-column: 1; grid-row: 2; align-self: start; padding: 0; container-type: inline-size; }
  .hero__title { font-size: min(1.75rem, 10.3cqi); }
  .hero__note { font-size: 0.9375rem; }
  .hero__sub { margin-top: 0.75rem; font-size: 1.0625rem; }
  /* The rating beside the button, as on a short phone held upright, so the
     pair takes one row. On a narrow band they wrap, rating under button. */
  .hero__actions { margin-top: 1rem; flex-direction: row; flex-wrap: wrap; align-items: center; column-gap: 0.5rem; }
  .hero__actions .rating { margin-top: 0; }
  /* Narrower link padding and switch gap, so the menu and the ID / EN switch
     stay on the logo row from 640 px wide (a second row cost the screen 44 px). */
  .menu a { padding-inline: 0.5rem; }
  .menu a:last-child { padding-right: 0; }
  .lang-switch { margin-left: 1rem; }
  /* The top screen tightened so the button and the rating clear the pinned
     bar (#44): less room between the lines, and a headline of 28 px at most. */
  .hero__top { padding-block: 2px; }
  .hero__note { margin-top: 0.25rem; }
  .hero__sub { margin-top: 0.5rem; }
  .hero__actions { margin-top: 0.5rem; }
}
/* Under 700 px wide the English menu and the switch only fit beside the logo
   with the name on two lines, CAELUS over JIU-JITSU, as on a phone held upright. */
@media (orientation: landscape) and (max-height: 500px) and (max-width: 699px) {
  .hero__name span { display: block; }
}
