/* One stylesheet for the whole site: the marketing pages and the legal texts
   share a single visual system, because they are the same business speaking.

   The language is Apple's, applied rather than copied: full-bleed sections on a
   near-white canvas, hierarchy built from surface shifts and hairlines instead
   of shadows, one blue that only ever fills a button, and typography carrying
   the weight through negative tracking that tightens as the size grows.

   Two deliberate departures from the reference:

   - The blue is #0071e3, chosen by the founder over the panel's #3a6fd0. The
     site and the panel are therefore a shade apart at the moment of handover;
     that was the accepted trade.
   - No web font. SF Pro is not served from anywhere we can link, and Inter
     would be a render-blocking request for a face that macOS and iOS replace
     with the system stack anyway. The Apple feel here comes from the tracking,
     not from the file. */

:root {
  /* ---- colour ---- */

  /* The only chromatic interactive colour, and only as a fill. Never text,
     never a border, never decoration. */
  --blue: #0071e3;
  --blue-hover: #0077ed;
  /* Outlined actions and inline links — deeper, quieter than the fill. */
  --link: #0066cc;
  /* Decorative only: the rule under a section eyebrow, nothing clickable. */
  --signal: #2997ff;

  --ink: #1d1d1f;
  --muted: #6e6e73;
  --ash: #707070;
  --hair: #d2d2d7;
  /* Осветлён на 20% доступного запаса 2026-08-24 (был #f5f5f7) по просьбе
     основателя: секция с маскотом читалась тускло. Двадцать процентов здесь —
     это два пункта, а не двадцать: до белого от 245 остаётся всего десять, и
     весь запас токена умещается в них. Взято столько, сколько просили, и не
     больше по причине: чередование `.canvas`/`.paper` держит ритм всей
     страницы, и чем ближе фрост к белому, тем слабее граница секций. На 247
     она ещё есть. Настоящая тусклость была не здесь — см. `.mascot`. */
  --frost: #f7f7f9;
  --white: #ffffff;
  --onyx: #000000;
  --pebble: #e2e2e5;

  /* ---- type ---- */

  --sans: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'SF Pro Display', 'Segoe UI', Roboto,
    'Helvetica Neue', Arial, sans-serif;

  /* ---- motion ---- */

  /* One curve and two durations for the entire site, so the page moves like a
     single object rather than a pile of separately-tuned effects. */
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --dur: 800ms;
  --dur-fast: 200ms;

  /* ---- shape ---- */

  --radius-pill: 980px;
  --radius-card: 8px;
  --radius-image: 18px;

  /* The one shadow in the system, and it grounds product images only. Never a
     card, never a button, never the nav. */
  --shadow-product: rgba(0, 0, 0, 0.18) 0 18px 60px;
}

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Anchors land below the fixed bar rather than under it. */
  scroll-padding-top: 4rem;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

body {
  font-family: var(--sans);
  color: var(--ink);
  background: var(--white);
  font-size: 1.0625rem; /* 17px — the reference's body size */
  line-height: 1.47;
  letter-spacing: -0.016em;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

/* ------------------------------------------------------------------ layout */

/* Sections stretch edge to edge; only the text inside is held to a column. */
section {
  padding: clamp(4rem, 11vw, 7.5rem) 1.5rem;
}

.hold {
  width: 100%;
  max-width: 61.25rem; /* 980px — the reference's internal text width */
  margin: 0 auto;
}

.hold--wide {
  max-width: 75rem;
}

.hold--narrow {
  max-width: 44rem;
}

.center {
  text-align: center;
}

.canvas {
  background: var(--frost);
}

.paper {
  background: var(--white);
}

.dark {
  background: var(--onyx);
  color: var(--white);
}

/* -------------------------------------------------------------------- type */

h1,
h2,
h3 {
  font-weight: 600;
  text-wrap: balance;
}

/* 56px at the top of the scale, tracking pulled in hard. */
.display {
  font-size: clamp(2.5rem, 6.4vw, 3.5rem);
  line-height: 1.07;
  letter-spacing: -0.015em;
}

/* 40–44px section headlines. */
.headline {
  font-size: clamp(2rem, 4.6vw, 2.75rem);
  line-height: 1.1;
  letter-spacing: -0.014em;
}

.subhead {
  margin-top: 1.25rem;
  font-size: clamp(1.25rem, 2.4vw, 1.625rem);
  line-height: 1.24;
  letter-spacing: -0.01em;
  /* 300 is the reference's whisper-voice weight, and it is what keeps a
     one-line descriptor from competing with the headline above it. */
  font-weight: 300;
  color: var(--ink);
  text-wrap: pretty;
}

.lede {
  font-size: 1.3125rem;
  line-height: 1.38;
  letter-spacing: -0.012em;
  font-weight: 300;
  color: var(--muted);
  text-wrap: pretty;
}

.body {
  color: var(--muted);
  text-wrap: pretty;
}

.caption {
  font-size: 0.75rem;
  line-height: 1.33;
  letter-spacing: -0.01em;
  color: var(--ash);
}

/* The small label over a section headline. Its rule is the one place the
   decorative blue is allowed to appear. */
.eyebrow {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ash);
}

.eyebrow::after {
  content: '';
  display: block;
  width: 1.75rem;
  height: 2px;
  margin-top: 0.75rem;
  border-radius: 2px;
  background: var(--signal);
  transform-origin: left;
  transition: transform var(--dur) var(--ease) 120ms;
}

.center .eyebrow::after {
  margin-inline: auto;
  transform-origin: center;
}

.dark .eyebrow {
  color: #a1a1a6;
}

/* `.subhead` красится в `--ink` — почти чёрный, и в тёмной секции это чёрным
   по чёрному. До 2026-08-24 единственный такой подзаголовок был спасён
   инлайновым цветом прямо в разметке; правило снимает заплатку и закрывает
   случай для всех следующих. Цвет тот же, что стоял инлайн, — кадр не
   меняется. Литерал, а не `--frost`: там поверхность, здесь текст, и одно
   значение у двух разных ролей уже однажды прочиталось как одна роль. */
.dark .subhead {
  color: #f5f5f7;
}

/* Тот же случай, что и у `.subhead` выше, и найден он тем же способом — замером,
   а не на глаз. `.caption` красится в `--ash` (#707070); на `--onyx` это
   отношение 4.2:1 при кегле 12px, то есть ниже нормы AA. Цвет взят у
   `.dark .eyebrow` — 8.1:1, — чтобы в тёмной секции не завелось третьего серого.
   Правило заведено до того, как в тёмной секции появилась первая подпись:
   иначе следующий, кто её поставит, унаследует нечитаемый текст молча. */
.dark .caption {
  color: #a1a1a6;
}

.stack > * + * {
  margin-top: 1.25rem;
}

/* ------------------------------------------------------------------- versus */

/* Two columns, and the argument is carried by their weight rather than by any
   mark: the left one is set in `--muted`, the right in `--ink`. No ticks, no
   crosses, no red. The section is not allowed to look like an attack on the
   software a salon already pays for — it says the two do different jobs, and a
   column of red crosses would say something else entirely.

   Not `.points`: that pattern (blue rule, h3, paragraph) already appears three
   times down this page, and a fourth would turn a comparison into another row
   of features. */
.versus {
  display: grid;
  gap: 1px;
  background: var(--hair);
  border: 1px solid var(--hair);
  border-radius: 14px;
  overflow: hidden;
  max-width: 46rem;
  margin-inline: auto;
  text-align: left;
}

@media (min-width: 46rem) {
  .versus {
    grid-template-columns: 1fr 1fr;
  }
}

.versus__side {
  background: var(--white);
  padding: 1.5rem 1.5rem 1.75rem;
}

.versus__who {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ash);
}

.versus__side--ours .versus__who {
  color: var(--ink);
}

.versus__side ul {
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
}

.versus__side li {
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--muted);
  padding: 0.6rem 0;
  border-top: 1px solid var(--hair);
}

.versus__side li:first-child {
  border-top: 0;
  padding-top: 0;
}

.versus__side--ours li {
  color: var(--ink);
}

/* -------------------------------------------------------------------- track */

/* One client's life between two visits. Vertical at every width, and that is a
   choice rather than a fallback: the owner reads this on a phone between two
   clients, and a horizontal timeline squeezed into 390px is four columns of
   eight-pixel type. Vertically the gap between visits is literal distance down
   the page — the thing the section is actually about. */
.track {
  position: relative;
  max-width: 34rem;
  margin-inline: auto;
  padding-left: 2.5rem;
  text-align: left;
}

/* Stops short at both ends rather than running the full height: a line that
   overshoots the first and last dot reads as a cropped section. */
.track::before {
  content: '';
  position: absolute;
  left: 0.4375rem;
  top: 0.6rem;
  bottom: 0.6rem;
  width: 1px;
  background: var(--hair);
}

.track__step {
  position: relative;
  padding-bottom: 2.25rem;
}

.track__step:last-child {
  padding-bottom: 0;
}

.track__dot {
  position: absolute;
  left: -2.5rem;
  top: 0.3rem;
  width: 0.9375rem;
  height: 0.9375rem;
  border-radius: 50%;
  background: var(--white);
  border: 1.5px solid var(--hair);
}

/* The one filled dot is the moment the product does its work — the day the
   cycle comes due. Everything above it is history, everything below is result. */
.track__step--now .track__dot {
  background: var(--blue);
  border-color: var(--blue);
}

.track__when {
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ash);
  font-variant-numeric: tabular-nums;
}

.track__what {
  font-size: 1.0625rem;
  line-height: 1.4;
  letter-spacing: -0.01em;
  margin-top: 0.3rem;
}

.track__meta {
  font-size: 0.875rem;
  color: var(--muted);
  margin-top: 0.3rem;
}

/* The waiting itself, drawn as a step with no dot: the gap on the line IS the
   28 days, so the label sits in it rather than beside it. */
.track__gap {
  position: relative;
  padding: 0.35rem 0 2.25rem;
  font-size: 0.8125rem;
  color: var(--ash);
  font-variant-numeric: tabular-nums;
}

.track__said {
  margin-top: 0.85rem;
  padding: 0.85rem 1rem;
  background: var(--frost);
  border-radius: 12px;
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ink);
}

/* `.canvas` is already frost, so a frost card on it is invisible — the same
   trap the conversation bubbles fell into, fixed the same way. */
.canvas .track__said {
  background: var(--white);
}

/* ---------------------------------------------------------------------- faq */

/* Built on `<details>`, and that is the whole point: it opens without a line of
   JavaScript, answers the keyboard, and is announced correctly by a screen
   reader. The script only counts which question was opened — take the script
   away and the section still works.

   Hairlines between rows rather than cards. Four sections of this page already
   use bordered cards; a fifth would read as a template, and a list of questions
   is a list, not a gallery. */
.faq {
  border-top: 1px solid var(--hair);
  text-align: left;
}

.faq__item {
  border-bottom: 1px solid var(--hair);
}

.faq__q {
  display: flex;
  gap: 1rem;
  align-items: baseline;
  justify-content: space-between;
  padding: 1.15rem 0;
  cursor: pointer;
  font-size: 1.0625rem;
  line-height: 1.45;
  letter-spacing: -0.01em;
  color: var(--ink);
  /* Both are needed: the second is the standards-track property, the first is
     what Safari still listens to. Without them the row keeps a stock triangle
     that no other control on this page has. */
  list-style: none;
}

.faq__q::-webkit-details-marker {
  display: none;
}

/* A sign drawn from two rules rather than a glyph: `+` and `−` in a font are
   different widths and sit off the baseline from each other, so the marker
   twitches as rows open. These do not move. */
.faq__sign {
  position: relative;
  flex: none;
  width: 0.75rem;
  height: 0.75rem;
  margin-top: 0.35rem;
}

.faq__sign::before,
.faq__sign::after {
  content: '';
  position: absolute;
  inset: 0;
  margin: auto;
  background: var(--muted);
  transition: transform 0.24s ease, opacity 0.24s ease;
}

.faq__sign::before {
  width: 100%;
  height: 1.5px;
}

.faq__sign::after {
  width: 1.5px;
  height: 100%;
}

.faq__item[open] .faq__sign::after {
  transform: scaleY(0);
  opacity: 0;
}

.faq__a {
  padding: 0 1.75rem 1.4rem 0;
  max-width: 60ch;
}

.faq__a p {
  color: var(--muted);
  font-size: 0.9375rem;
  line-height: 1.6;
}

.faq__a p + p {
  margin-top: 0.75rem;
}

@media (prefers-reduced-motion: reduce) {
  .faq__sign::before,
  .faq__sign::after {
    transition: none;
  }
}

/* ----------------------------------------------------------------- actions */

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.25rem;
  align-items: center;
  margin-top: 2rem;
}

.center .actions {
  justify-content: center;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  /* 44px floor: the same hit target the panel respects, and the salon owner is
     tapping this with wet hands between clients. */
  min-height: 2.75rem;
  padding: 0 1.375rem;
  border-radius: var(--radius-pill);
  font-size: 1.0625rem;
  letter-spacing: -0.016em;
  text-decoration: none;
  border: 1px solid transparent;
  transition:
    background-color var(--dur-fast) var(--ease),
    color var(--dur-fast) var(--ease),
    border-color var(--dur-fast) var(--ease),
    transform 100ms ease-out;
}

.btn--fill {
  background: var(--blue);
  color: var(--white);
}

.btn--fill:hover {
  background: var(--blue-hover);
}

.btn--out {
  border-color: var(--link);
  color: var(--link);
}

.btn--out:hover {
  background: rgba(0, 102, 204, 0.06);
}

.dark .btn--out {
  border-color: #6e6e73;
  color: var(--white);
}

.dark .btn--out:hover {
  background: rgba(255, 255, 255, 0.08);
}

/* Feedback on the press, not on the release: the page answers the finger
   before it lifts. */
.btn:active {
  transform: scale(0.97);
}

.link {
  color: var(--link);
  text-decoration: none;
  text-underline-offset: 0.2em;
}

.link:hover {
  text-decoration: underline;
}

.link svg {
  vertical-align: -1px;
  transition: transform 300ms var(--ease);
}

.link:hover svg {
  transform: translateX(3px);
}

/* --------------------------------------------------------------------- nav */

.nav {
  position: sticky;
  top: 0;
  z-index: 20;
  /* Apple's own bar: not white, but the page seen through frosted glass. The
     opaque fallback is what browsers without backdrop-filter get. */
  background: rgba(255, 255, 255, 0.86);
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur-fast) linear;
}

@supports (backdrop-filter: blur(20px)) or (-webkit-backdrop-filter: blur(20px)) {
  .nav {
    background: rgba(255, 255, 255, 0.72);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
    backdrop-filter: saturate(180%) blur(20px);
  }
}

/* The hairline is not painted until the page has moved: at rest the bar and the
   canvas are one surface. */
.nav.is-scrolled {
  border-bottom-color: var(--hair);
}

.nav__inner {
  max-width: 75rem;
  margin: 0 auto;
  padding: 0.5rem 1.5rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1.25rem;
  min-height: 3rem;
}

/* On a phone the four links do not fit beside the brand and the sign-in link,
   and a scrolling strip would put a half-cut word right next to "Giriş yap".
   They drop to their own row instead: every destination stays visible, and
   nothing hides behind a menu the owner has to discover. */
@media (max-width: 51.99rem) {
  /* The bar is two rows tall here, so an anchor has further to clear. */
  html {
    scroll-padding-top: 5.5rem;
  }

  .nav__inner {
    padding-bottom: 0.625rem;
  }

  .nav__brand {
    margin-right: auto;
  }

  .nav__links {
    order: 3;
    width: 100%;
    margin-inline: 0;
    justify-content: center;
    gap: 1.25rem;
  }
}

/* The reference sets nav links at 12px, and at Apple's density that works. On
   a 1440-wide page with four links it reads as fine print, so the whole bar
   moves up one step of our own scale: links to 14px, the wordmark to 17px so
   the hierarchy between them survives. */
.nav__brand {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--ink);
  text-decoration: none;
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: -0.015em;
  flex: none;
}

.nav__brand img {
  width: 1.5rem;
  height: 1.5rem;
}

.nav__links {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  margin-inline: auto;
  /* On a phone the row scrolls rather than wraps — the same pattern the panel's
     own bar uses, so the two feel like one product. */
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}

.nav__links::-webkit-scrollbar {
  display: none;
}

.nav__links a {
  font-size: 0.875rem;
  letter-spacing: -0.014em;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
  opacity: 0.8;
  transition: opacity var(--dur-fast) linear;
}

.nav__links a:hover,
.nav__links a[aria-current='page'] {
  opacity: 1;
}

.nav__signin {
  flex: none;
  font-size: 0.875rem;
  letter-spacing: -0.014em;
  color: var(--link);
  text-decoration: none;
  white-space: nowrap;
}

/* Dokunma hedefi.

   Ölçüldü, tahmin edilmedi: 390 pikselde başlıktaki bağlantıların dokunma
   alanı 21 piksel yüksekliğindeydi; kabul edilen alt sınır 44. En önemlisi
   "Giriş yap" — panele açılan tek kapı, ve ürünün kendi tarifine göre salon
   sahibi onu iki müşteri arasında, ayakta, telefonla açıyor.

   Yükseklik `min-height` ile değil, dolgu artı negatif marj ile büyütülüyor:
   böylece bağlantı hem parmak için büyür, hem de satırın yüksekliğini ve
   metnin yerini değiştirmez. Görünen sayfa aynı kalır, değişen yalnızca
   ıskalanan dokunuşların sayısıdır. */
.nav__links a,
.nav__signin {
  display: inline-flex;
  align-items: center;
  padding-block: 0.75rem;
  margin-block: -0.75rem;
  padding-inline: 0.375rem;
  margin-inline: -0.375rem;
}

.nav__signin:hover {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* ------------------------------------------------------------------ images */

/* The product shot is the only thing in the system allowed a shadow, and it is
   what grounds it against the canvas. */
.shot {
  margin-top: clamp(2.5rem, 6vw, 4rem);
  border-radius: var(--radius-image);
  box-shadow: var(--shadow-product);
  /* A hairline over the shadow: the panel's own background is nearly the same
     grey as the canvas, and without an edge the screenshot dissolves into it. */
  outline: 1px solid rgba(0, 0, 0, 0.06);
  outline-offset: -1px;
}

.shot--phone {
  max-width: 17.5rem;
  margin-inline: auto;
  border-radius: 2rem;
}

/* --------------------------------------------------------------- the mascot

   The words are positioned as a share of the artwork, never in pixels: the
   plaques were measured once inside the finished image, and a percentage keeps
   them on their plaques at every width without a media query for each.

   `container-type: inline-size` is what makes the type scale with the picture.
   A fixed font-size would fit the plaques at one width and spill at every
   other; `cqw` is a share of this container, so the label keeps its proportion
   to the plaque it sits on the way a printed sign does. If the mascot is ever
   redrawn, the four percentages below have to be measured again — that is the
   one price of keeping the text out of the file, and it is paid once per
   version rather than on every language, every rename and every screen. */

.mascot {
  container-type: inline-size;
  position: relative;
  /* Ровно ширина `.hold--narrow`, в котором фигурка и стоит: она заполняет
     свою колонку, а не висит в ней с полями. Было 34rem, и замер показал, чем
     это платилось — таблички в рисунке имеют лицо #eff0f3 против фона #f7f7f9,
     то есть держатся почти одной тенью (контраст 1.07). Тень растёт вместе с
     рисунком, поэтому крупнее здесь читается как «ярче», хотя ни один цвет не
     тронут. Если `.hold--narrow` когда-нибудь сменит ширину — сменить и здесь,
     иначе поля вернутся. */
  max-width: 44rem;
  margin-inline: auto;
  /* Отступ снизу больше обычного ритма секции: у фигурки нет прямоугольного
     края — нижние щупальца заканчиваются в пустоте, и надзаголовок, стоящий на
     штатном расстоянии, читается прилипшим к ним. Меряется по тому, где
     кончается рисунок, а не по тому, где кончается его коробка. */
  margin-bottom: clamp(2rem, 5vw, 3.25rem);
}

.mascot__art {
  display: block;
  width: 100%;
  height: auto;
}

.mascot__tag {
  position: absolute;
  left: var(--x);
  top: var(--y);
  /* The independent `translate` property, not `transform` — and that is the
     whole reason the labels can also carry `.rise`. The entrance sets
     `transform: translateY(16px)` and then `transform: none`, which would wipe
     a centring translate written the old way and leave every label hanging off
     its plaque by half its own width. Two properties, two jobs, no conflict. */
  translate: -50% -50%;
  /* Never wraps: a two-line label inside a one-line plaque is worse than a
     small one, and the plaque cannot grow. */
  white-space: nowrap;
  font-size: 3.4cqw;
  font-weight: 590;
  letter-spacing: -0.01em;
  color: var(--ink);
}

/* A browser without the independent property gets the centring back through
   `transform`, and loses the entrance in exchange — the labels are simply
   there. Correct placement is content; the stagger is not. */
@supports not (translate: 0) {
  .mascot__tag {
    transform: translate(-50%, -50%);
  }

  .js .mascot__tag.rise {
    opacity: 1;
    transform: translate(-50%, -50%);
  }
}

/* --------------------------------------------------------------- the thread

   A conversation quoted, not a screen impersonated: no device frame, no
   WhatsApp green, no status bar. Borrowing another product's chrome to look
   convincing is exactly the cheapness this section is meant to answer, and it
   would also be a trademark we were not given.

   Bubbles are the one place the 8px card radius is wrong: a chat bubble that
   is not round does not read as speech. They take the pill radius instead,
   softened at the tail corner — the same two radii the rest of the page uses,
   in the one arrangement that means something here. */

/* A conversation is read in a column, not across a page. At the section's full
   980px the same four lines look like a transcript; at 30rem they look like a
   phone without anyone having to draw one. */
.thread__label,
.thread {
  max-width: 30rem;
  margin-inline: auto;
}

.thread__label {
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
  color: var(--muted);
  text-align: left;
}

.thread {
  /* `relative`, because the typing indicator is placed over the bubble that has
     not arrived yet rather than inserted before it. Inserting would change the
     column's height mid-play and shove the rest of the page down while somebody
     is reading it — the single most expensive-looking mistake this whole
     section could make. */
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
  margin-top: 0.875rem;
  text-align: left;
}

.bubble {
  max-width: 85%;
  padding: 0.6875rem 1rem;
  font-size: 0.9375rem;
  line-height: 1.45;
  letter-spacing: -0.006em;
  border-radius: 1.125rem;
}

/* Her side has to be a surface, not just text: on a `paper` section the frost
   reads as a bubble, on a `canvas` one it is the section's own colour and the
   message stops looking like a message at all. Same override the identity block
   already makes for the same reason. */
.bubble--in {
  align-self: flex-start;
  border-bottom-left-radius: var(--radius-card);
  background: var(--frost);
  color: var(--ink);
}

.canvas .bubble--in {
  background: var(--white);
}

.bubble--out {
  align-self: flex-end;
  border-bottom-right-radius: var(--radius-card);
  background: var(--blue);
  color: var(--white);
}

/* Three dots in a bubble of their own, laid over the message that is still
   coming. Sized and placed by script, because where it sits is where the next
   bubble already is. */
.thread__typing {
  position: absolute;
  display: flex;
  gap: 0.25rem;
  align-items: center;
  padding: 0.6875rem 0.875rem;
  border-radius: 1.125rem;
  border-bottom-right-radius: var(--radius-card);
  background: var(--blue);
  opacity: 0;
  transition: opacity var(--dur-fast) linear;
}

.thread__typing.is-on {
  opacity: 1;
}

.thread__typing span {
  width: 0.3125rem;
  height: 0.3125rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.85);
  animation: thread-dot 1.2s infinite;
}

.thread__typing span:nth-child(2) {
  animation-delay: 0.15s;
}

.thread__typing span:nth-child(3) {
  animation-delay: 0.3s;
}

@keyframes thread-dot {
  0%,
  60%,
  100% {
    opacity: 0.35;
    transform: translateY(0);
  }
  30% {
    opacity: 1;
    transform: translateY(-2px);
  }
}

/* ------------------------------------------------- the three threads, tabbed

   Three conversations in one place, because the point is the comparison: the
   same salon handing the assistant more or less of the work. Spread across the
   page they would be three anecdotes; stacked here they are a ladder.

   Switched by hand, never on a timer. An auto-rotating carousel takes the one
   thing a reader has — control — and on a phone it swaps the paragraph out
   from under a thumb that was still reading it.

   The stack is a single grid cell holding all three panels, so the row is as
   tall as the tallest and the height NEVER changes when tabs are switched.
   Reserving that height is the same bargain the bubbles already make one level
   down, and it costs the shorter two some empty space: `align-self: center`
   spends it above and below rather than dumping it all underneath. A stack
   that sized itself to the current panel would shove the rest of the page up
   and down on every click, which is the one thing this section must not do. */

/* Without JS the tabs would be three dead buttons, so they are simply not
   there: the panels fall back to plain flow, one under another, and each says
   in its own sentence which arrangement it shows. Everything is readable, in
   order, with nothing hidden and nothing to press. */
.threads__tabs {
  display: none;
}

.threads__lead {
  font-size: 0.9375rem;
  color: var(--muted);
}

/* One frame around the group, not three around the words — which is how the
   founder drew it, and it is also the truer shape: these are three states of one
   switch, not three separate buttons. Bare labels on the section's own surface
   were invisible on first read; a control has to look like a thing you can
   press before anyone will press it.

   `inline-flex` so the frame shrinks to its contents and the centred section
   centres it; a stretched border would read as a divider across the column. */
.js .threads__tabs {
  display: inline-flex;
  /* Wraps to a second line rather than scrolling sideways. A strip you have to
     drag is exactly the complaint §15 records about the app's own nav, and it
     would arrive here at 390px where three Turkish labels never fit one row. */
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.25rem;
  margin-top: 0.875rem;
  padding: 0.25rem;
  border: 1px solid var(--ink);
  border-radius: var(--radius-pill);
}

.threads__tab {
  /* 44px, the project's own floor for a tap target (§15 in BACKLOG.md records
     it for the app's buttons, and this is the site's first real control on a
     phone). Padding alone left them at 38 — measured, not assumed — so the
     minimum is stated and the box centres its label inside it. */
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  padding: 0.5rem 0.9375rem;
  border: 0;
  border-radius: var(--radius-pill);
  background: none;
  font: inherit;
  font-size: 0.9375rem;
  color: var(--muted);
  cursor: pointer;
  transition:
    background-color var(--dur-fast) linear,
    color var(--dur-fast) linear;
}

.threads__tab:hover {
  color: var(--ink);
}

/* Filled with ink, not with blue. Blue is the page's interactive fill and it is
   already carrying the assistant's bubbles a few centimetres below — a blue
   pill here would read as one more message. Ink inside an ink frame reads as
   the selected segment of a switch and nothing else. */
.threads__tab[aria-selected='true'] {
  background: var(--ink);
  color: var(--white);
  font-weight: 590;
}

.threads__tab:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 2px;
}

/* Air between the control and what it controls. Needed most on the tallest
   panel, where the conversation starts right under the tabs and the two read as
   one block without it; the shorter panels get theirs from `align-self` anyway. */
.threads__stack {
  margin-top: 1.75rem;
}

.threads__panel + .threads__panel {
  margin-top: 3rem;
}

.js .threads__stack {
  display: grid;
}

.js .threads__panel {
  grid-area: 1 / 1;
  align-self: center;
  margin-top: 0;
}

.js .threads__panel:not(.is-current) {
  visibility: hidden;
}

/* The consequence, in the product's own sentence, under the conversation that
   shows it. Two of these three threads are answered by a PERSON — the owner —
   and this line is where the page says so; without it the blue bubbles would
   read as the assistant's in all three, which is the exact claim the section
   must not make by accident. */
.thread__note {
  max-width: 30rem;
  margin: 0.9375rem auto 0;
  font-size: 0.875rem;
  line-height: 1.45;
  color: var(--muted);
  text-align: left;
  text-wrap: pretty;
}

.thread__note b {
  font-weight: 590;
  color: var(--ink);
}

/* ------------------------------------------------------------------- lists */

.points {
  display: grid;
  gap: 2.5rem;
  margin-top: clamp(3rem, 7vw, 4.5rem);
  text-align: left;
}

@media (min-width: 46rem) {
  .points {
    grid-template-columns: repeat(3, 1fr);
    gap: 2.5rem;
  }
}

/* Four points do not fit three columns. Two by two first, then one row of four
   once there is room — at 1200px that is 270px a column, which four short
   Turkish headings survive. */
@media (min-width: 46rem) {
  .points--four {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 64rem) {
  .points--four {
    grid-template-columns: repeat(4, 1fr);
    gap: 2rem;
  }
}

.point h3 {
  font-size: 1.3125rem;
  line-height: 1.24;
  letter-spacing: -0.012em;
}

.point p {
  margin-top: 0.625rem;
  font-size: 1.0625rem;
  color: var(--muted);
  text-wrap: pretty;
}

.dark .point p {
  color: #a1a1a6;
}

.point .rule {
  display: block;
  width: 1.75rem;
  height: 2px;
  margin-bottom: 1rem;
  border-radius: 2px;
  background: var(--signal);
  transform-origin: left;
  transition: transform var(--dur) var(--ease) 120ms;
}

/* ------------------------------------------------------------------ plans */

/* Three plans with no card behind them. The reference is explicit that a panel
   inside a `--frost` section breaks the spatial logic — the canvas is the
   surface — so the columns are separated by hairlines and nothing else. */
.plans {
  display: grid;
  margin-top: clamp(3rem, 7vw, 4.5rem);
  border-top: 1px solid var(--hair);
  text-align: left;
}

.plan {
  padding: 2rem 0;
  border-bottom: 1px solid var(--hair);
}

@media (min-width: 52rem) {
  .plans {
    grid-template-columns: repeat(3, 1fr);
    border-bottom: 1px solid var(--hair);
  }

  .plan {
    padding: 2.5rem 2rem;
    border-bottom: 0;
    border-left: 1px solid var(--hair);
  }

  .plan:first-child {
    border-left: 0;
    padding-left: 0;
  }

  .plan:last-child {
    padding-right: 0;
  }
}

.plan__name {
  font-size: 1.75rem;
  line-height: 1.18;
  letter-spacing: -0.014em;
}

.plan__who {
  margin-top: 0.375rem;
  font-size: 0.9375rem;
  color: var(--muted);
}

.plan__price {
  margin-top: 1.5rem;
  display: flex;
  align-items: baseline;
  gap: 0.375rem;
}

.plan__amount {
  font-size: 2.5rem;
  line-height: 1.1;
  letter-spacing: -0.014em;
  font-weight: 600;
  /* Turkish price formatting: 1.990, not 1,990. Written into the markup rather
     than computed, because there is nothing here to compute. */
  font-variant-numeric: tabular-nums;
}

/* Stands in the amount's place until the amounts are confirmed. Smaller than a
   number would be — a price is a number and should look like one, and a phrase
   set at 40px only draws attention to what is missing. */
.plan__amount--soon {
  font-size: 1.5rem;
  letter-spacing: -0.012em;
}

.plan__per {
  font-size: 1.0625rem;
  color: var(--muted);
  font-weight: 400;
}

/* What the number already includes. Deliberately quiet and deliberately there:
   a salon that reads "5.000" and is billed 6.000 has been misled once, and the
   whole page is an argument that we do not do that. */
.plan__note {
  margin-top: 0.625rem;
  font-size: 0.8125rem;
  color: var(--muted);
}

.plan__list {
  margin-top: 1.5rem;
  list-style: none;
  font-size: 0.9375rem;
  color: var(--muted);
}

.plan__list li {
  position: relative;
  padding-left: 1.25rem;
}

.plan__list li + li {
  margin-top: 0.625rem;
}

/* A hairline tick rather than a bullet glyph: the same 1px vocabulary as every
   other divider on the page. */
.plan__list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.5rem;
  width: 0.5rem;
  height: 0.25rem;
  border-left: 1.5px solid var(--ink);
  border-bottom: 1.5px solid var(--ink);
  transform: rotate(-45deg);
  opacity: 0.55;
}

.plan__cta {
  margin-top: 1.5rem;
  font-size: 0.9375rem;
}

.setup {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 2rem;
  align-items: flex-start;
  justify-content: space-between;
  padding: 2rem 0;
  border-bottom: 1px solid var(--hair);
  text-align: left;
}

.setup > div {
  max-width: 40rem;
}

.setup__name {
  font-size: 1.3125rem;
  line-height: 1.24;
  letter-spacing: -0.012em;
}

.setup__price {
  margin-top: 0;
}

/* ------------------------------------------------------------------ notes */

/* A third texture, on purpose. The page already has two rows of blue-ruled
   points; a third would make it read as a template built from one block. These
   are separated by a hairline above instead, set smaller, and carry no colour
   at all. */
.notes {
  display: grid;
  gap: 2rem;
  margin-top: clamp(3rem, 7vw, 4rem);
  text-align: left;
}

@media (min-width: 46rem) {
  .notes {
    grid-template-columns: repeat(3, 1fr);
    gap: 2.5rem;
  }
}

.note {
  padding-top: 1.25rem;
  border-top: 1px solid var(--hair);
}

.note h3 {
  font-size: 1.0625rem;
  line-height: 1.29;
  letter-spacing: -0.016em;
}

.note p {
  margin-top: 0.5rem;
  font-size: 0.9375rem;
  color: var(--muted);
  text-wrap: pretty;
}

/* --------------------------------------------------------------- identity */

/* The trading identity. Not decoration: a registered business in Turkey has to
   publish this, the payment provider compares it against the documents it was
   given, and Meta's business verification does the same. */
.identity {
  margin-top: 2rem;
  padding: 1.5rem;
  border: 1px solid var(--hair);
  border-radius: var(--radius-card);
  background: var(--white);
  text-align: left;
}

.canvas .identity {
  background: var(--white);
}

.identity dl {
  display: grid;
  gap: 0.625rem 1.5rem;
  font-size: 0.9375rem;
}

@media (min-width: 34rem) {
  .identity dl {
    grid-template-columns: max-content 1fr;
  }
}

.identity dt {
  color: var(--muted);
}

.identity a {
  color: var(--link);
  text-underline-offset: 0.2em;
}

/* ------------------------------------------------------------------ footer */

.foot {
  background: var(--frost);
  padding: 3rem 1.5rem 4rem;
  font-size: 0.75rem;
  line-height: 1.5;
  letter-spacing: -0.01em;
  color: var(--ash);
}

.foot__inner {
  max-width: 75rem;
  margin: 0 auto;
}

.foot__cols {
  display: grid;
  gap: 2rem;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  padding-bottom: 2rem;
  border-bottom: 1px solid var(--hair);
}

.foot h4 {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 0.75rem;
}

.foot ul {
  list-style: none;
}

.foot li + li {
  margin-top: 0.625rem;
}

.foot a {
  color: var(--ash);
  text-decoration: none;
}

.foot a:hover {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* Ödeme yöntemleri. iyzico'nun kendi logo paketinden, dokunulmadan: kart
   şemalarının logoları başkasının markası, yeniden çizilmez. */
.foot__pay {
  padding-top: 1.5rem;
}

.foot__pay img {
  display: block;
  width: 26.8125rem; /* 429px, the band's own size */
  max-width: 100%;
  height: auto;
}

.foot__fine {
  padding-top: 1.5rem;
}

.foot__fine p + p {
  margin-top: 0.5rem;
}

/* ------------------------------------------------------------------- prose */

/* The legal texts. Prose only, no entrance animation: someone reading a privacy
   policy is looking for a sentence, not being introduced to a brand. */
.prose {
  max-width: 44rem;
  margin: 0 auto;
  padding: clamp(3rem, 7vw, 4.5rem) 1.5rem clamp(4rem, 8vw, 5rem);
  line-height: 1.6;
}

.prose h1 {
  font-size: clamp(2rem, 5vw, 2.75rem);
  line-height: 1.1;
  letter-spacing: -0.014em;
}

.prose .updated {
  margin-top: 0.75rem;
  font-size: 0.875rem;
  color: var(--muted);
}

.prose h2 {
  margin-top: 2.75rem;
  font-size: 1.3125rem;
  letter-spacing: -0.012em;
}

.prose h3 {
  margin-top: 1.75rem;
  font-size: 1.0625rem;
}

.prose p,
.prose ul,
.prose ol {
  margin-top: 1rem;
  text-wrap: pretty;
}

.prose ul,
.prose ol {
  padding-left: 1.25rem;
}

.prose li {
  margin-top: 0.5rem;
}

.prose a {
  color: var(--link);
  text-underline-offset: 0.2em;
}

.prose strong {
  font-weight: 600;
}

.prose .identity {
  margin-top: 1.5rem;
  background: var(--frost);
}

/* Wide content scrolls inside its own box rather than pushing the page sideways
   on a phone, which is where most of this will be read. */
.table-scroll {
  margin-top: 1.5rem;
  overflow-x: auto;
  border: 1px solid var(--hair);
  border-radius: var(--radius-card);
}

table {
  border-collapse: collapse;
  width: 100%;
  min-width: 34rem;
  font-size: 0.9375rem;
}

th,
td {
  padding: 0.875rem 1rem;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--hair);
}

tr:last-child td {
  border-bottom: 0;
}

th {
  font-weight: 600;
  font-size: 0.8125rem;
  color: var(--muted);
  background: var(--frost);
}

/* ---------------------------------------------------------------- entrance */

/* Everything that moves in does the same thing: a short rise with a fade. The
   stagger is a custom property on the element, so adding a block is one
   attribute rather than another keyframe.

   Scoped to `.js`, which an inline script in the head sets before this rule can
   apply. If that script never runs — blocked, failed, an old browser — nothing
   is ever hidden, so a broken animation costs the page its motion and not its
   content. */
.js .rise {
  opacity: 0;
  transform: translateY(16px);
  transition:
    opacity var(--dur) var(--ease) var(--delay, 0ms),
    transform var(--dur) var(--ease) var(--delay, 0ms);
}

.js .rise.is-visible {
  opacity: 1;
  transform: none;
}

/* The product shot arrives slightly under-scaled, the way Apple lands a device
   render: it settles into the page instead of being already there. */
.js .shot {
  opacity: 0;
  transform: scale(0.965) translateY(24px);
  transition:
    opacity 1000ms var(--ease),
    transform 1000ms var(--ease);
}

.js .shot.is-visible {
  opacity: 1;
  transform: none;
}

/* `visibility`, not `display` or `opacity: 0` on a collapsed box — and this is
   the whole trick. A hidden-by-visibility bubble keeps its layout box, so the
   column is already its finished height before the first word arrives. The
   conversation then plays inside a space that never moves, and nothing below it
   shifts while somebody is reading.

   Done the obvious way — bubbles appended one at a time — the page would grow
   four times under the reader's thumb. That is what a cheap site does.

   Scoped to `[data-threads]` rather than to every `.thread`, because hiding is
   only ever correct where something will later un-hide it. The tabbed set is
   the one place with a player; a `.thread` used anywhere else on the page — the
   captured refusal further down — has nobody to reveal it, and under the old
   selector it would have been hidden for good. One page, one animated
   conversation is also the right amount: a second one competing with it would
   be motion for its own sake. */
.js [data-threads] .bubble {
  visibility: hidden;
  opacity: 0;
  transform: translateY(8px);
  transition:
    opacity 320ms var(--ease),
    transform 320ms var(--ease);
}

/* Scoped to the open panel, and that is not tidiness — it is the one thing
   holding the stack together. `visibility` is inherited, but a descendant may
   set itself back to `visible` and escape a hidden ancestor. A bubble that has
   already been said keeps `is-said` forever, so without `.is-current` here
   every thread the reader had already watched would go on showing THROUGH the
   panel on top of it, four lines overlapping two. */
.js .threads__panel.is-current .thread .bubble.is-said {
  visibility: visible;
  opacity: 1;
  transform: none;
}

.js .eyebrow::after,
.js .point .rule {
  transform: scaleX(0);
}

.js .is-visible .rule,
.js .eyebrow.is-visible::after,
.js .is-visible .eyebrow::after {
  transform: scaleX(1);
}

/* Motion is decoration here; the content is identical without it. Anyone who
   has asked their system to calm down gets the page fully formed. */
@media (prefers-reduced-motion: reduce) {
  .js .rise,
  .js .shot {
    opacity: 1;
    transform: none;
    transition: none;
  }

  /* The conversation is content, not decoration: without motion it is simply
     there, every line, from the first paint. The script checks the same query
     and never plays.

     Still only the open panel — for the same reason as `is-said` above. Written
     unscoped, this rule would hand every hidden thread a `visibility: visible`
     of its own and print all three on top of each other, and it would do it
     only for readers who asked their system to calm down. */
  .js .threads__panel.is-current .thread .bubble {
    visibility: visible;
    opacity: 1;
    transform: none;
    transition: none;
  }

  .thread__typing span {
    animation: none;
  }

  .js .eyebrow::after,
  .js .point .rule {
    transform: scaleX(1);
    transition: none;
  }

  .btn,
  .link svg {
    transition: none;
  }
}

/* -------------------------------------------------------------------- lost

   Четыре реплики, на которые никто не ответил. Пузырь берётся существующий —
   `.bubble--in`, тот самый, что во всех разговорах ниже, — и в этом весь приём:
   там под входящим всегда стоит исходящий, здесь не стоит ничего. Молчание
   нарисовано, а не описано.

   Секция чёрная (разметка объясняет, почему именно чёрная), и пузырю нужна
   третья поверхность: на белом он фростовый, на фросте белый, на чёрном —
   #1d1d1f. Тот же подъём на тон, которым вся система строит иерархию вместо
   теней. */
.dark .bubble--in {
  background: #1d1d1f;
  color: #f5f5f7;
}

.lost {
  display: grid;
  gap: 2.5rem;
  margin-top: clamp(3rem, 7vw, 4.5rem);
  text-align: left;
}

@media (min-width: 46rem) {
  .lost {
    grid-template-columns: repeat(2, 1fr);
    gap: 3rem;
  }
}

@media (min-width: 64rem) {
  .lost {
    grid-template-columns: repeat(4, 1fr);
    gap: 2.5rem 2rem;
  }
}

/* 85% от узкой колонки — это обрубок в две строки, а реплика клиентки
   короткая и должна читаться одной. */
.lost .bubble {
  max-width: 100%;
}

.lost__after {
  margin-top: 1rem;
}

.lost__after p {
  font-size: 1.0625rem;
  line-height: 1.35;
  color: #a1a1a6;
  text-wrap: pretty;
}

.lost__after p + p {
  margin-top: 0.5rem;
}

/* Вторая строка — то, что меняется, — светлее первой: потеря уходит в серый,
   поворот выходит в цвет текста. Тот же приём, которым `.versus` ведёт спор
   весом, а не галочками. Оба цвета уже стоят в системе для тёмной секции,
   новых здесь нет. Селектор в два класса, чтобы выиграть у `.lost__after p`
   специфичностью, а не `!important`. */
.lost__after p.lost__turn {
  color: #f5f5f7;
}

/* ----------------------------------------------------------------- dossier

   Карточка клиентки и предложение, собранное из неё. Половины намеренно не
   равны по весу: слева данные — мелко, таблично, серым; справа фраза
   ассистента — крупно, в цвет чернил. Читатель должен увидеть не «две
   колонки», а «вот из этого получилось вот это».

   Карточка белая на фросте, как `.identity`, и по той же причине: панель
   ломает пространственную логику только тогда, когда её поверхность совпадает
   с поверхностью секции. */
.dossier {
  display: grid;
  gap: 2rem;
  margin-top: clamp(2.5rem, 6vw, 3.5rem);
  text-align: left;
}

@media (min-width: 52rem) {
  .dossier {
    grid-template-columns: 22rem 1fr;
    gap: 3rem;
    align-items: start;
  }
}

.dossier__card {
  padding: 1.5rem;
  border: 1px solid var(--hair);
  border-radius: var(--radius-card);
  background: var(--white);
}

.dossier__card dl {
  display: grid;
  gap: 0.75rem 1.25rem;
  font-size: 0.9375rem;
  /* Единственное место на сайте, где цифры выстраиваются столбиком, и
     единственная причина завести здесь табличные. */
  font-variant-numeric: tabular-nums;
}

@media (min-width: 26rem) {
  .dossier__card dl {
    grid-template-columns: max-content 1fr;
  }
}

.dossier__card dt {
  color: var(--muted);
}

.dossier__card dd {
  color: var(--ink);
}

.dossier__label {
  margin-bottom: 0.875rem;
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
  color: var(--muted);
}

.dossier__said {
  font-size: clamp(1.1875rem, 2.2vw, 1.4375rem);
  line-height: 1.32;
  letter-spacing: -0.012em;
  font-weight: 300;
  color: var(--ink);
  text-wrap: pretty;
}

.dossier__note {
  margin-top: 1.25rem;
}

/* ------------------------------------------------------------------- hands

   Человек и ассистент. Похоже на `.versus` ровно настолько, насколько похожи
   две колонки, и отличается тем, ради чего блок стоит: у `.versus` колонки
   спорят, здесь они складываются. Складывает их полоса внизу, пересекающая
   обе, — её у `.versus` нет и не должно быть.

   Обе колонки в `--ink`, и это тоже расхождение с `.versus`: приглушить
   человеческую половину значило бы назвать её второсортной за три строки до
   предложения, которое утверждает обратное. Контраст несут слова. */
.hands {
  margin-top: clamp(2.5rem, 6vw, 3.5rem);
  border-top: 1px solid var(--hair);
  text-align: left;
}

.hands__pair {
  display: grid;
}

@media (min-width: 46rem) {
  .hands__pair {
    grid-template-columns: 1fr 1fr;
  }
}

.hands__side {
  padding: 1.75rem 0;
}

@media (min-width: 46rem) {
  .hands__side + .hands__side {
    padding-left: 2.5rem;
    border-left: 1px solid var(--hair);
  }
}

@media (max-width: 45.99rem) {
  .hands__side + .hands__side {
    border-top: 1px solid var(--hair);
  }
}

.hands__who {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ash);
}

.hands__side ul {
  margin-top: 1.125rem;
  list-style: none;
  font-size: 1.0625rem;
  line-height: 1.45;
}

.hands__side li {
  color: var(--ink);
}

.hands__side li + li {
  margin-top: 0.5rem;
}

/* Полоса, ради которой блок не `.versus`. */
.hands__join {
  padding-top: 1.5rem;
  border-top: 1px solid var(--hair);
  font-size: clamp(1.125rem, 2vw, 1.3125rem);
  line-height: 1.3;
  letter-spacing: -0.012em;
  font-weight: 300;
  text-wrap: pretty;
}

/* --------------------------------------------------------------------- day

   День администратора. Часы — единственная колонка цифр на странице, поэтому
   табличные; «до» серым, «после» чернилами — снова спор весом, без галочек,
   крестиков и красного. */
.day {
  margin-top: clamp(2.5rem, 6vw, 3.5rem);
  border-top: 1px solid var(--hair);
  text-align: left;
}

.day__head {
  display: none;
}

@media (min-width: 46rem) {
  .day__head,
  .day__row {
    display: grid;
    grid-template-columns: 6rem 1fr 1fr;
    gap: 2rem;
  }

  .day__head {
    padding: 0.875rem 0;
    border-bottom: 1px solid var(--hair);
  }
}

.day__col {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ash);
}

.day__row {
  padding: 1.5rem 0;
  border-bottom: 1px solid var(--hair);
}

.day__time {
  font-size: 0.9375rem;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}

.day__was,
.day__now {
  font-size: 1.0625rem;
  line-height: 1.4;
  text-wrap: pretty;
}

.day__was {
  color: var(--muted);
}

.day__now {
  color: var(--ink);
}

/* На узком экране колонок нет — есть час, а под ним две подписанные строки.
   Подписи берутся из `data-when` и появляются только здесь, потому что шапки
   таблицы на этой ширине уже нет. */
@media (max-width: 45.99rem) {
  .day__was,
  .day__now {
    margin-top: 0.75rem;
  }

  .day__was::before,
  .day__now::before {
    content: attr(data-when);
    display: block;
    margin-bottom: 0.125rem;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ash);
  }
}

/* ------------------------------------------------------------- plan facts

   Три-четыре строки под списком пакета: до какого уровня доходит ассистент,
   обязательна ли установка, как с нами связаться. В колонке шириной в треть
   страницы двухколоночный `dl` встал бы в две буквы на строку, поэтому пара
   идёт друг под другом — подпись микрокапителью, как `.eyebrow` и
   `.hands__who`, значение обычным текстом. Отделены волосяной линией сверху,
   как `.note`: это сноска к пакету, а не ещё один список его свойств. */
.plan__facts {
  margin-top: 1.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--hair);
}

.plan__facts dt {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ash);
}

.plan__facts dd {
  margin-top: 0.25rem;
  font-size: 0.9375rem;
  line-height: 1.4;
  color: var(--ink);
  text-wrap: pretty;
}

.plan__facts dd + dt {
  margin-top: 0.875rem;
}