/* Alderway Dental, variant b5.
   Reference: Watts Pet, structure only. One typeface for the entire page, from
   the nine pixel labels to the cropped wordmark, with hierarchy carried by very
   large scale jumps and nothing else. No second family, no italic, no serif.
   Exactly one saturated accent, and it owns whole panels rather than appearing
   as small highlights, which is the reference's rule. The ground is inverted to
   off white so that an accent strong enough to own a panel does not turn a
   dental practice into a product launch.
   The shape of the container changes at every section on purpose: full bleed
   band, two-up split, dragged scale, horizontal scroller, rounded pill. If they
   were all the same stacked band this reference would have been wasted. */

:root {
  --ground: #F1F1F1;
  --white: #FFFFFF;
  --ink: #191919;
  --mute: #5E5E5E;
  --line: #D6D6D6;
  --accent: #8C4A2F;
  --accent-ink: #FBF3EF;

  --sans: 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;

  --pad: clamp(1.25rem, 4vw, 3rem);
  --gap: clamp(3rem, 7vw, 5.5rem);
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1.0625rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img { display: block; max-width: 100%; height: auto; }
a { color: inherit; }

.wrap {
  width: 100%;
  max-width: 74rem;
  margin-inline: auto;
  padding-inline: var(--pad);
}

.skip {
  position: absolute;
  left: -9999px;
  background: var(--ink);
  color: var(--white);
  padding: 0.9rem 1.25rem;
  z-index: 50;
  text-decoration: none;
}
.skip:focus { left: 0; top: 0; }

:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }

/* ---------- header ---------- */

.top { border-bottom: 1px solid var(--line); }
.top__in {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 0.4rem;
}
.mark {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-weight: 800;
  font-size: 1.15rem;
  letter-spacing: -0.03em;
  text-transform: uppercase;
  text-decoration: none;
}
.top__meta { margin: 0; font-size: 0.88rem; font-weight: 500; }

/* ---------- fold ---------- */

.fold { position: relative; overflow: hidden; padding-bottom: clamp(2rem, 5vw, 3.5rem); }
.fold__media { position: relative; }
.fold__media img {
  width: 100%;
  height: clamp(16rem, 42vw, 30rem);
  object-fit: cover;
  filter: saturate(0.75) contrast(1.02);
}
.fold__in { padding-top: clamp(1.5rem, 4vw, 2.5rem); }

.fold__h {
  margin: 0 0 1.25rem;
  font-weight: 800;
  font-size: clamp(2.6rem, 8.5vw, 6.5rem);
  line-height: 0.9;
  letter-spacing: -0.035em;
  text-transform: uppercase;
}
.fold__sub { max-width: 40rem; margin: 0 0 1.75rem; color: var(--mute); }
.fold__act { margin: 0; }

.btn {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0.6rem 1.6rem;
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
  font-size: 0.98rem;
  text-decoration: none;
  border-radius: 999px;
  transition: background 0.18s ease;
}
.btn:hover { background: #753C25; }

/* The wordmark cropped by an edge, at fold scale. Decorative and hidden from
   assistive technology because the real name is in the header. */
/* The wordmark is set to the viewport rather than to the page gutter. At 19vw
   inside the gutter it was 51 to 84 pixels too wide at every width below about
   1400 and was being silently clipped, which reads as broken rather than as
   cropped. "ALDERWAY" measures 5.44em in this face at this tracking, so 18vw
   spans about 98 percent of the viewport and fits at every size, phone
   included, while being larger than it was before. */
.fold__mark, .end__mark {
  margin: 0;
  padding-inline: 0;
  text-align: center;
  font-weight: 800;
  font-size: 18vw;
  line-height: 0.72;
  letter-spacing: -0.06em;
  text-transform: uppercase;
  overflow: hidden;
  user-select: none;
}
.fold__mark { color: #8A8A8A; margin-top: clamp(1.5rem, 4vw, 3rem); }
.end__mark { color: #6E6E6E; margin-top: clamp(2rem, 5vw, 3.5rem); }

/* ---------- static row, not a ticker ---------- */

.facts { background: var(--ink); color: var(--white); }
.facts__row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 0.5rem 2.5rem;
  padding-block: 1.1rem;
}
.facts__item { margin: 0; font-size: 0.9rem; color: #B9B9B9; }
.facts__item b {
  font-weight: 800;
  font-size: 1.3rem;
  letter-spacing: -0.03em;
  color: var(--white);
  margin-right: 0.35rem;
}

/* ---------- two-up split ---------- */

.h2 {
  max-width: 20ch;
  margin: 0 0 1.35rem;
  font-weight: 800;
  font-size: clamp(1.8rem, 4.2vw, 3rem);
  line-height: 0.98;
  letter-spacing: -0.045em;
  text-transform: uppercase;
}
.h2--light { color: var(--white); }

.two { padding-block: var(--gap); }
.two__in {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}
.two__text { max-width: 38rem; }
.two__text p { margin: 0 0 1rem; color: var(--mute); }
.two__text p:last-child { margin-bottom: 0; }

.two__panel {
  padding: 2rem 1.75rem;
  background: var(--white);
  border: 1px solid var(--line);
}
.two__stat {
  margin: 0 0 0.5rem;
  font-weight: 800;
  font-size: clamp(3.5rem, 9vw, 5.5rem);
  line-height: 0.85;
  letter-spacing: -0.05em;
  color: var(--accent);
}
.two__note { margin: 0; font-size: 0.95rem; color: var(--mute); }

/* ---------- full bleed statement band, in the accent ---------- */

.band { background: var(--accent); color: var(--accent-ink); }
.band__line {
  max-width: 46rem;
  margin-inline: auto;
  padding: clamp(2.5rem, 6vw, 4rem) var(--pad);
  text-align: center;
  font-weight: 700;
  font-size: clamp(1.35rem, 3.4vw, 2.3rem);
  line-height: 1.3;
  letter-spacing: -0.03em;
}

/* ---------- the scale ---------- */

.scale { padding-block: var(--gap); }
.scale__lede { max-width: 44rem; margin: 0 0 2rem; color: var(--mute); }

.scrub {
  padding: 1.25rem 1.5rem 1.4rem;
  background: var(--white);
  border: 1px solid var(--line);
}
.scrub__label {
  display: block;
  margin-bottom: 0.6rem;
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--mute);
}
.scrub__input { width: 100%; min-height: 44px; accent-color: var(--accent); cursor: pointer; }
.scrub__ticks {
  display: flex;
  justify-content: space-between;
  margin: 0.15rem 0 0;
  font-weight: 700;
  font-size: 0.85rem;
  color: var(--mute);
  font-variant-numeric: tabular-nums;
}
.scrub__read { margin: 0.7rem 0 0; font-size: 0.92rem; color: var(--mute); }
.scrub__read b { color: var(--ink); }

/* With scripting off the scrubber is meaningless, so it is not shown at all
   and all four stages render as an ordinary readable list. */
.scrub { display: none; }
.js .scrub { display: block; }

.stages { margin: 2rem 0 0; padding: 0; list-style: none; }


.stage { padding-top: 1.5rem; border-top: 2px solid var(--ink); margin-bottom: 2rem; }
.stage:last-of-type { margin-bottom: 0; }
.stage__when {
  margin: 0 0 1rem;
  font-weight: 800;
  font-size: 1.5rem;
  letter-spacing: -0.035em;
  text-transform: uppercase;
}
.stage__cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: 1.25rem;
}
.stage__col { display: flex; flex-direction: column; }
.stage__body { flex: 1 1 auto; }
.stage__col { padding: 1.25rem 1.35rem 1.4rem; }
.stage__col--watch { background: var(--white); border: 1px solid var(--line); }
.stage__col--drill { background: #E6E4E2; border: 1px solid var(--line); }
.stage__h {
  margin: 0 0 0.6rem;
  font-weight: 800;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.18em;
}
.stage__col--watch .stage__h { color: var(--accent); }
.stage__col--drill .stage__h { color: var(--mute); }
.stage__body { margin: 0 0 1rem; font-size: 0.95rem; color: var(--mute); }
.stage__cost {
  margin: 0;
  padding-top: 0.8rem;
  border-top: 1px solid var(--line);
  font-weight: 700;
  font-size: 1rem;
}

.scale__foot { max-width: 56ch; margin: 2.25rem 0 0; font-size: 0.95rem; color: var(--mute); }


/* ---------- the drawings ---------- */

/* The tooth is a public domain anatomical cross section from Wikimedia Commons,
   inlined once as a symbol and referenced by every stage. Only the marks on top
   of it change, and which marks show is decided by each stage's own data-stage,
   so with scripting off all four render correctly. */
.defs { position: absolute; width: 0; height: 0; overflow: hidden; }

/* Without align-self the svg stretches to the full column width in a flex
   column and the figure sits small in a wide empty box. */
.tooth {
  display: block;
  align-self: start;
  height: clamp(9rem, 17vw, 13.5rem);
  width: auto;
  aspect-ratio: 3090 / 5895;
  margin: 0 0 1rem;
}

/* The mark, the filling that replaces it and the replacement that eventually
   replaces that are one ellipse at three sizes. Scaling about its own centre
   keeps them concentric with no arithmetic on my part. */
.t-spot, .t-fill, .t-origin, .t-ghost { transform-box: fill-box; transform-origin: center; }

.t-spot { fill: var(--accent); transform: scale(0.6); }
.t-fill { fill: #6E6E6E; stroke: #191919; stroke-width: 14; }
/* These are drawn in a 3090 unit space and displayed about 130 pixels wide, so
   a 16 unit stroke lands under a pixel and disappears. The outline of what was
   actually there before the drill is the strongest thing on this page and it
   has to survive at display size. */
.t-origin { fill: none; stroke: #F5F1EA; stroke-width: 36; stroke-dasharray: 62 48; transform: scale(0.55); }
.t-ghost { fill: none; stroke: var(--accent); stroke-width: 32; stroke-dasharray: 66 52; transform: scale(1.45); }

/* The watched tooth is never cut, so it has no filling, no removed enamel and
   no future replacement. Only the mark, fading. */
.stage__col--watch .t-fill,
.stage__col--watch .t-origin,
.stage__col--watch .t-ghost { display: none; }

.stage[data-stage="0"] .stage__col--watch .t-spot { opacity: 0.95; }
.stage[data-stage="1"] .stage__col--watch .t-spot { opacity: 0.66; }
.stage[data-stage="2"] .stage__col--watch .t-spot { opacity: 0.46; }
.stage[data-stage="3"] .stage__col--watch .t-spot { opacity: 0.24; }

/* The drilled tooth never shows the mark, because the mark is gone: it was cut
   out along with more enamel than it occupied. At month 0 the outline of what
   was actually there is drawn inside the filling, which is the 2mm point made
   visible. At month 24 the dashed shape is the size of the replacement. */
.stage__col--drill .t-spot { display: none; }
.stage__col--drill .t-origin { display: none; }
.stage[data-stage="0"] .stage__col--drill .t-origin { display: block; }
.stage__col--drill .t-ghost { display: none; }
.stage[data-stage="3"] .stage__col--drill .t-ghost { display: block; }


/* ---------- the live panel ---------- */

/* Each column is one thing: a label, the drawing it belongs to, and the note for
   the month you are on. Before this the drawings floated in a band of their own
   above two unlabelled boxes and neither one said which column it was. */
.live {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
  gap: 1.25rem;
  margin-top: 2rem;
}
.live__col {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 1.25rem 1.35rem 1.4rem;
  border: 1px solid var(--line);
}
.live__col--watch { background: var(--white); }
.live__col--drill { background: #E6E4E2; }

.live__h {
  align-self: stretch;
  margin: 0 0 0.9rem;
  font-weight: 800;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.18em;
}
.live__col--watch .live__h { color: var(--accent); }
.live__col--drill .live__h { color: var(--mute); }

.live .tooth { align-self: center; margin: 0 0 1.1rem; }

/* The four notes for this column occupy one cell and cross-fade, so the panel
   does not change height as the scale moves. visibility, not opacity alone, so
   the three that are not showing are out of the accessibility tree. */
.live__notes { align-self: stretch; display: grid; }
.live__note { grid-area: 1 / 1; opacity: 0; visibility: hidden; transition: opacity 0.26s ease, visibility 0s linear 0.26s; }
.live__note.is-on { opacity: 1; visibility: visible; transition: opacity 0.26s ease, visibility 0s; }
.live__note p { margin: 0; }
.live__note .stage__body { font-size: 0.95rem; color: var(--mute); }
.live__col--drill .live__note .stage__body { color: #5A5651; }
.live__note .stage__cost {
  margin-top: 0.9rem;
  padding-top: 0.8rem;
  border-top: 1px solid var(--line);
  font-weight: 700;
  font-size: 1rem;
}

/* Every mark reads its value from a custom property that the script writes on
   each frame of a drag. No transition and no keyframe here on purpose: the value
   is already continuous, and easing it again only puts lag between the thumb and
   the drawing. */
.live .tooth--watch .t-spot { opacity: var(--spot-o, 0.95); }
.live .tooth--watch .t-fill,
.live .tooth--watch .t-origin,
.live .tooth--watch .t-ghost { display: none; }

.live .tooth--drill .t-spot { display: none; }
.live .tooth--drill .t-fill { display: block; }
.live .tooth--drill .t-origin { display: block; opacity: var(--origin-o, 1); }
.live .tooth--drill .t-ghost {
  display: block;
  opacity: var(--ghost-o, 0);
  transform: scale(var(--ghost-s, 1.25));
}

/* Once the notes have been moved into the panel the four stages are the
   scripting-off view and nothing more. */
.js .stages { display: none; }

/* ---------- the pin ---------- */

.scale__track { position: relative; }
.scale__pin { position: static; }

/* Only wide screens pin. On a phone the two columns stack, the pinned block
   would be taller than the viewport, and there would be nothing left to scroll
   with. There the scrubber is the whole interaction. */
@media (min-width: 60rem) and (min-height: 40rem) {
  .js .scale__track { height: 340vh; }
  .js .scale__pin {
    position: sticky;
    top: 0;
    display: flex;
    align-items: center;
    min-height: 100svh;
  }
  .js .scale__pin > .wrap { width: 100%; }
}

/* Somebody who has asked for less motion should not be given a section that
   changes under them as they scroll. They get the plain list instead. */
@media (prefers-reduced-motion: reduce) {
  .js .scale__track { height: auto; }
  .js .scale__pin { position: static; min-height: 0; display: block; }
}

/* ---------- view transitions ---------- */

/* The view transition that used to run on the stage swap has been removed. It
   is the right tool for a discrete change between two states, and this control
   is no longer discrete: the drawing now interpolates and the notes cross-fade,
   so a transition on top of that was both redundant and a source of aborts on
   every frame of a drag. */

/* ---------- horizontal scroller with items that open in place ---------- */

.causes { padding-block: var(--gap) clamp(2rem, 5vw, 3rem); background: var(--ink); color: var(--white); }
.causes .h2 { color: var(--white); }
.causes__lede { max-width: 40rem; margin: 0 0 2rem; color: #B9B9B9; }

.rail {
  display: flex;
  gap: 1rem;
  margin: 0;
  padding-block: 0 1.25rem;
  padding-inline: max(var(--pad), calc((100% - 74rem) / 2 + var(--pad)));
  list-style: none;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scrollbar-width: thin;
}
.cause {
  flex: 0 0 20rem;
  scroll-snap-align: start;
  align-self: start;
  background: #262626;
  border: 1px solid #3A3A3A;
}
.cause details { padding: 1.15rem 1.25rem 1.25rem; }
.cause summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 44px;
}
.cause summary::-webkit-details-marker { display: none; }
.cause summary::after {
  content: "+";
  font-weight: 700;
  font-size: 1.35rem;
  line-height: 1;
  color: var(--accent-ink);
}
.cause details[open] summary::after { content: "\2212"; }
.cause__t { font-weight: 700; font-size: 1.02rem; letter-spacing: -0.015em; }
.cause details p {
  margin: 0.85rem 0 0;
  padding-top: 0.85rem;
  border-top: 1px solid #3A3A3A;
  font-size: 0.93rem;
  color: #B9B9B9;
}

/* ---------- the rounded pill, with its own controls ---------- */

.pill { padding-block: var(--gap); background: var(--ink); }
.pill__body {
  padding: clamp(1.75rem, 4vw, 3rem);
  background: var(--accent);
  color: var(--accent-ink);
  border-radius: clamp(1.5rem, 4vw, 3rem);
}
.pill__h {
  max-width: 18ch;
  margin: 0 0 1.5rem;
  font-weight: 800;
  font-size: clamp(1.5rem, 3.4vw, 2.4rem);
  line-height: 1;
  letter-spacing: -0.04em;
  text-transform: uppercase;
}
.pill__list { margin: 0; padding: 0; list-style: none; }
.pill__item { margin-bottom: 1rem; }
.pill__item:last-child { margin-bottom: 0; }
.pill__item p { margin: 0; max-width: 44rem; font-size: clamp(1rem, 1.6vw, 1.15rem); }

/* Scripting on: one at a time, with controls. Off: all three, stacked. */
.js .pill__item { display: none; }
.js .pill__item.is-on { display: block; }
.js .pill__nav { display: flex; }

.pill__nav {
  display: none;
  align-items: center;
  gap: 1rem;
  margin-top: 1.75rem;
  padding-top: 1.25rem;
  border-top: 1px solid rgba(251, 243, 239, 0.3);
}
.pill__btn {
  min-width: 44px;
  min-height: 44px;
  background: transparent;
  color: var(--accent-ink);
  border: 1px solid rgba(251, 243, 239, 0.55);
  border-radius: 999px;
  font: inherit;
  font-size: 1.05rem;
  cursor: pointer;
}
.pill__btn:hover { background: rgba(251, 243, 239, 0.14); }
.pill__count { margin: 0; font-weight: 700; font-size: 0.9rem; font-variant-numeric: tabular-nums; }

/* ---------- end ---------- */

.end { padding-block: var(--gap) 0; background: var(--ink); color: var(--white); overflow: hidden; }
.end__in {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}
.end__p { max-width: 32rem; margin: 0; color: #B9B9B9; }
.end__facts { margin: 0; }
.end__facts > div {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1.5rem;
  padding-block: 0.65rem;
  border-bottom: 1px solid #3A3A3A;
  font-size: 0.95rem;
}
.end__facts dt { color: #B9B9B9; }
.end__facts dd { margin: 0; text-align: right; font-weight: 500; }

/* ---------- footer ---------- */

.foot { padding-block: 2.5rem; background: var(--ink); color: #B9B9B9; }
.foot p { max-width: 56ch; margin: 0 0 0.6rem; font-size: 0.84rem; }
.foot b { color: var(--white); font-weight: 700; }
.foot a {
  display: inline-block;
  padding-block: 0.7rem;
  margin-block: -0.7rem;
  color: var(--white);
  text-underline-offset: 3px;
}

/* ---------- reveals ---------- */

/* Where the browser has scroll-driven animations, the reveal is pure CSS: it
   runs on the compositor and needs no scroll listener and no observer. Where it
   does not, the observer in script.js still runs and this file hides the
   elements for it. Content is visible in both paths and in the no-script path. */

/* The reveal moves and does not fade. Two reasons. A scroll-driven fade leaves
   every below-the-fold element at opacity 0 at rest, which on this page was 58%
   of the text, and a page whose content is invisible until scrolled has a
   failure mode with no upside. And a repeated fade-up is on our own list of
   things not to reach for. A short rise reads as well and nothing is ever
   invisible. */

@supports (animation-timeline: view()) {
  @keyframes reveal {
    from { transform: translateY(14px); }
    to { transform: none; }
  }
  [data-reveal] {
    animation: reveal linear both;
    animation-timeline: view();
    animation-range: entry 0% entry 55%;
  }
}

@supports not (animation-timeline: view()) {
  .js [data-reveal] { transform: translateY(14px); }
  .js [data-reveal].is-in {
    transform: none;
    transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
  }
}

/* A scroll timeline has no meaning on paper. */
@media print {
  [data-reveal] { animation: none; transform: none; }
}

/* ---------- narrow ---------- */

@media (max-width: 54rem) {
  .two__in { grid-template-columns: 1fr; }
  .end__in { grid-template-columns: 1fr; }
  .cause { flex-basis: 16rem; }
}

@media (prefers-reduced-motion: reduce) {
  .js [data-reveal],
  .js [data-reveal].is-in { transform: none; transition: none; }
  [data-reveal] { animation: none; transform: none; }
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none; }
}
