/* Klar — marketing site
   A 1:1 implementation of "Klar Landing A" from the Klar design system
   (claude.ai/design). Every value below comes from that file or from the
   system's own components; the additions are the ones a design canvas does not
   need and a real page does: responsive breakpoints, focus-visible rings,
   reduced-motion, and print. Those are marked where they appear.

   Tokens live in tokens/. Nothing here hard-codes a colour. */

@import url('tokens/colors.css');
@import url('tokens/fonts.css');
@import url('tokens/typography.css');
@import url('tokens/spacing.css');

/* ---- Base ------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  padding-bottom: 1px; /* contains the footer's bottom margin */
  background: var(--color-bg-subtle);
  color: var(--color-text);
  font-family: var(--font-ui);
  -webkit-font-smoothing: antialiased;
}

/* The UA rule for [hidden] is display:none at element specificity, so any
   class here that sets display would quietly beat it. It must not. */
[hidden] {
  display: none !important;
}

a {
  color: var(--color-link);
  text-decoration: none;
}

a:hover {
  color: var(--color-link-hover);
}

img {
  max-width: 100%;
}

h1,
h2,
h3,
p {
  text-wrap: pretty;
}

/* Keyboard focus only — the design draws no ring, but a page you can tab
   through needs one. Emerald, per --color-focus-ring. */
:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 10;
  padding: 12px 18px;
  border-radius: 0 0 var(--radius-md) 0;
  background: var(--color-accent);
  color: var(--color-accent-contrast);
  font: var(--text-ui-headline);
}

.skip-link:focus {
  left: 0;
  color: var(--color-accent-contrast);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---- Language ----------------------------------------------------------
   Both languages ship in the markup; the lang attribute on <html> decides
   which one is drawn. German renders with no JS at all. */

[data-en] {
  display: none;
}

html[lang='en'] [data-en] {
  display: inline;
}

html[lang='en'] [data-de] {
  display: none;
}

/* ---- Shell ------------------------------------------------------------ */

.shell {
  max-width: 1100px;
  margin: 0 auto;
  padding-left: 32px;
  padding-right: 32px;
}

.section {
  padding-top: 72px;
}

/* ---- Header ----------------------------------------------------------- */

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding-top: 22px;
  padding-bottom: 22px;
}

.wordmark {
  display: flex;
  align-items: center;
  /* The system specifies the lockup gap as 0.45x the mark height. */
  gap: 14px;
  color: var(--color-text);
}

.wordmark:hover {
  color: var(--color-text);
}

.wordmark__mark {
  display: block;
  width: 32px;
  height: 32px;
}

.wordmark__text {
  font: 700 19px/1 var(--font-ui);
  letter-spacing: var(--tracking-wordmark);
  color: var(--color-text);
}

.header__controls {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* Segmented pill group — theme and language switches.
   Drawn as the design system's SegmentedControl, not as an accent-filled pill:
   a tinted track with the active segment raised on a hairline. The landing file
   filled the active segment with --color-accent, which made a preference switch
   the loudest emerald above the fold and left the CTA competing with it. The
   accent means "this is the action" everywhere else on the page; chrome does
   not get to borrow it. */
.seg {
  display: flex;
  gap: 2px;
  padding: 4px;
  border-radius: var(--radius-pill);
  background: var(--color-surface-tint);
}

.seg__btn {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 8px 13px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--color-text-tertiary);
  font: 600 13px/1 var(--font-ui);
  cursor: pointer;
  transition: background var(--duration-base) var(--ease-standard),
    color var(--duration-base) var(--ease-standard),
    border-color var(--duration-base) var(--ease-standard);
}

.seg__btn:hover {
  color: var(--color-text);
}

.seg__btn[aria-pressed='true'] {
  background: var(--color-surface-raised);
  border-color: var(--color-border-subtle);
  color: var(--color-text);
  box-shadow: var(--shadow-sm);
}

.seg__btn svg {
  flex: 0 0 auto;
}

/* ---- Controls ---------------------------------------------------------
   Button and Input, ported from the design system's own components
   (components/core/Button.jsx, components/forms/Input.jsx). */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 46px;
  padding: 13px 22px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  background: var(--color-accent);
  color: var(--color-accent-contrast);
  font: 600 16px/1 var(--font-ui);
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--duration-base) var(--ease-standard),
    transform var(--duration-fast) var(--ease-standard);
}

.btn:hover {
  background: var(--color-accent-strong);
  color: var(--color-accent-contrast);
}

/* --color-accent-strong is emerald-500 in dark, i.e. the resting colour.
   Step the other way so the hover still reads. */
[data-theme='dark'] .btn:hover {
  background: var(--emerald-600);
}

.btn:active {
  transform: scale(0.97);
}

.field {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 11px 14px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  transition: border-color var(--duration-base) var(--ease-standard);
}

.field:focus-within {
  border-color: var(--color-accent);
}

.field input {
  flex: 1;
  min-width: 0;
  border: none;
  outline: none;
  background: transparent;
  font: var(--text-ui-body);
  color: var(--color-text);
}

.field input::placeholder {
  color: var(--color-text-tertiary);
}

/* Both controls carry the same 46px hint in the design; stretch keeps them
   the same height once the field's line box makes it the taller of the two. */
.signup {
  display: flex;
  align-items: stretch;
  gap: 10px;
}

.signup > .field {
  flex: 1;
}

.cta-note {
  font: var(--text-ui-body-sm);
  color: var(--color-text-tertiary);
  margin: 12px 0 0;
}

.cta-done {
  font: var(--text-ui-body);
  color: var(--color-accent-strong);
  padding: 13px 0;
}

/* ---- Hero -------------------------------------------------------------- */

.hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 480px);
  gap: 40px;
  align-items: center;
  padding-top: 40px;
}

/* One grid item on desktop so the copy centres against the shot as a block.
   It dissolves at the mobile breakpoint, see below. */
.hero__copy {
  min-width: 0;
}

.hero__title {
  /* The 38px floor put this on three lines at 402pt and pushed the product
     shot off the first screen. 30px holds two lines on the narrowest phones
     and the clamp reaches the design's 56px well before tablet width. */
  font: 700 clamp(30px, 5.6vw, 56px) / 1.04 var(--font-ui);
  letter-spacing: var(--tracking-display-xl);
  margin: 0 0 20px;
}

.hero__lead {
  font: 400 20px/1.5 var(--font-ui);
  color: var(--color-text-secondary);
  margin: 0 0 36px;
  max-width: 26em;
}

.hero__cta {
  max-width: 460px;
}

.hero__note {
  font: var(--text-ui-body-sm);
  color: var(--color-text-tertiary);
  margin: 24px 0 0;
}

/* ---- Hero demo -----------------------------------------------------------
   The app's Übersicht card, rebuilt in markup rather than photographed. Every
   value was measured off the shipped screen and every one of them turned out
   to be a token this page already carries:

     card #FFFFFF   --color-surface        month  #5C7078  --color-text-tertiary
     rule #E6F2F0   --color-border-subtle  figure #15272B  --color-text
     mark #02C39A   --color-accent         label  #44585E  --color-text-secondary
     rest #BFD8D4   --color-border-strong  dots   --teal-700 / --cyan-600

   Proportions follow the screen too: the app insets row content by 5% of the
   card, and the marks are 6.2:1 pills with a gap a quarter of their height.
   Nothing here is invented; it is the same system drawing itself. */

.hero__demo {
  margin: 0;
}

/* Names what the app actually covers. The page never said it anywhere else,
   and a visitor who uses something other than alcohol had no way to tell
   whether this was built for them. */
.hero__demo-caption {
  font: var(--text-ui-body-sm);
  color: var(--color-text-tertiary);
  margin-top: 16px;
  text-wrap: pretty;
}

.quota {
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  padding-bottom: 28px;
}

.quota__month {
  margin: 0;
  padding: 20px 24px 16px;
  border-bottom: 1px solid var(--color-border-subtle);
  font: var(--text-ui-caption);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-text-tertiary);
}

.quota__row {
  padding: 22px 24px 0;
}

/* The hairline belongs between rows, inset to the content, never around the
   card. That is the system's RowDivider rule. */
.quota__row + .quota__row {
  margin-top: 22px;
  border-top: 1px solid var(--color-border-subtle);
  padding-top: 22px;
}

.quota__name {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 10px;
  font: var(--text-ui-headline);
  color: var(--color-text);
}

.quota__dot {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--teal-700);
  flex: 0 0 auto;
}

.quota__dot--cyan {
  background: var(--cyan-600);
}

.quota__figure {
  display: flex;
  align-items: baseline;
  gap: 7px;
  margin: 0 0 14px;
  font: var(--text-ui-body);
  color: var(--color-text-secondary);
}

.quota__figure b {
  font: var(--text-ui-numeral);
  color: var(--color-text);
}

/* Marks share the row equally, so six and ten both reach the same edges. */
.quota__pips {
  display: flex;
  gap: 8px;
}

.quota__pips i {
  flex: 1;
  height: 10px;
  border-radius: var(--radius-pill);
  border: 1.5px solid var(--color-border-strong);
}

/* Filled means still available, which is why four of six are lit at "Noch 4". */
.quota__pips i.is-left {
  background: var(--color-accent);
  border-color: var(--color-accent);
}

/* ---- Section headings -------------------------------------------------- */

.section__title {
  font: var(--text-display-md);
  letter-spacing: var(--tracking-display-md);
  margin: 0 0 40px;
  max-width: 20em;
}

.section__note {
  font: var(--text-ui-body-sm);
  color: var(--color-text-tertiary);
  margin: 20px 0 0;
}

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

.grid-2 {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 24px;
}

.grid-3 {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
}

.card {
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  padding: 32px;
}

/* The system's one recurring decoration: a solid circle badge holding a
   white-stroke icon. */
.card__badge {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--color-accent);
  margin-bottom: 20px;
}

.card__badge--cyan {
  background: var(--cyan-600);
}

.card__title {
  font: var(--text-display-sm);
  letter-spacing: var(--tracking-display-sm);
  margin: 0 0 12px;
}

.card__quote {
  font: var(--text-ui-body);
  font-style: italic;
  color: var(--color-text);
  margin: 0 0 10px;
}

.card__body {
  font: var(--text-ui-body);
  color: var(--color-text-secondary);
  margin: 0 0 10px;
}

.card__meta {
  font: var(--text-ui-body-sm);
  color: var(--color-text-secondary);
  margin: 0;
}

/* ---- Privacy block (inverse) ------------------------------------------- */

.inverse {
  background: var(--color-bg-inverse);
  border-radius: var(--radius-lg);
  padding: 48px;
}

.inverse__title {
  font: var(--text-display-md);
  letter-spacing: var(--tracking-display-md);
  color: var(--white);
  margin: 0 0 12px;
  max-width: 20em;
}

.inverse__lead {
  font: 400 17px/1.55 var(--font-ui);
  color: var(--teal-100);
  margin: 0 0 40px;
  max-width: 34em;
}

.inverse .grid-3 {
  gap: 32px;
}

.inverse__icon {
  display: block;
  margin-bottom: 14px;
}

.inverse__item-title {
  font: var(--text-ui-headline);
  color: var(--white);
  margin: 0 0 6px;
}

.inverse__item-body {
  font: var(--text-ui-body-sm);
  color: var(--teal-100);
  margin: 0;
}

/* ---- Evidence ---------------------------------------------------------- */

.evidence__card {
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  padding: 28px;
}

.evidence__icon {
  display: block;
  margin-bottom: 18px;
}

.evidence__claim {
  font: var(--text-ui-headline);
  margin: 0 0 8px;
}

.evidence__body {
  font: var(--text-ui-body-sm);
  color: var(--color-text-secondary);
  margin: 0;
}

.evidence__limit {
  font: var(--text-ui-body-sm);
  color: var(--color-text-tertiary);
  margin: 24px 0 0;
  max-width: 46em;
}

/* ---- Closing CTA band --------------------------------------------------- */

.cta-band {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 32px;
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  padding: 40px 48px;
}

.cta-band__title {
  font: var(--text-display-sm);
  letter-spacing: var(--tracking-display-sm);
  margin: 0;
}

.cta-band .signup {
  flex: 1;
  min-width: 340px;
  max-width: 460px;
}

/* In the band the confirmation replaces a form that was vertically centred,
   so it carries no leading of its own. */
.cta-band .cta-done {
  padding: 0;
}

/* ---- Help -------------------------------------------------------------- */

.help {
  padding-top: 64px;
}

.help__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 32px;
  border-top: 1px solid var(--color-border);
  padding-top: 32px;
}

.help__item {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

.help__icon {
  flex: 0 0 auto;
  margin-top: 2px;
}

.help__title {
  font: var(--text-ui-headline);
  margin: 0 0 2px;
}

.help__title a {
  color: var(--color-text);
}

.help__title a:hover {
  color: var(--color-link-hover);
}

.help__detail {
  font: var(--text-ui-body-sm);
  color: var(--color-text-tertiary);
  margin: 0;
}

/* ---- Footer ------------------------------------------------------------ */

.site-footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding-top: 48px;
  padding-bottom: 56px;
  font: var(--text-ui-body-sm);
  color: var(--color-text-tertiary);
}

.site-footer__mark {
  display: flex;
  align-items: center;
  gap: 10px;
}

.site-footer__mark img {
  display: block;
  width: 18px;
  height: 18px;
}

.site-footer__mark span {
  font: 700 13px/1 var(--font-ui);
  letter-spacing: var(--tracking-wordmark);
  color: var(--color-text-secondary);
}

.site-footer__nav {
  display: flex;
  gap: 22px;
}

/* ---- Responsive --------------------------------------------------------
   Not in the design file — that canvas is one desktop width. The breakpoints
   only collapse the grids and tighten the gutter; no value above changes. */

@media (max-width: 960px) {
  /* Single column, and the product shot moves up between the copy and the
     form. Stacked in source order it landed behind six text elements, i.e.
     entirely below the fold on a phone — the one asset that shows what this
     is was the last thing anyone saw. display:contents dissolves the copy
     wrapper so its two halves become grid items and the shot can sit between
     them. The div carries no semantics, so nothing is lost with it. */
  .hero {
    grid-template-columns: minmax(0, 1fr);
    /* Tightened from 32px: it buys the last pixels that put the whole CTA
       above the fold on a 780px screen. */
    row-gap: 24px;
  }

  .hero__copy {
    display: contents;
  }

  .hero__intro {
    order: 1;
  }

  .hero__demo {
    order: 2;
    max-width: 420px;
    margin-inline: auto;
    width: 100%;
  }

  .hero__actions {
    order: 3;
  }

  /* row-gap now carries this space. */
  .hero__lead {
    margin-bottom: 0;
  }

  .grid-3,
  .inverse .grid-3,
  .help__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .inverse {
    padding: 40px;
  }

  .cta-band {
    padding: 32px;
  }
}

@media (max-width: 680px) {
  .shell {
    padding-left: 20px;
    padding-right: 20px;
  }

  .section,
  .help {
    padding-top: 56px;
  }

  .grid-2,
  .grid-3,
  .inverse .grid-3,
  .help__grid {
    grid-template-columns: minmax(0, 1fr);
  }

  /* The header wrapped to two rows here and ate 126px of a 780px screen
     before the page had said anything. Dropping the theme labels to icons
     puts it back on one row; the words stay in the accessibility tree. */
  .site-header {
    gap: 12px;
    padding-top: 12px;
    padding-bottom: 12px;
  }

  .seg__label {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .seg__btn {
    gap: 0;
    padding: 8px 12px;
  }

  .hero__lead {
    font-size: 18px;
  }

  .card,
  .inverse {
    padding: 28px;
  }

  .cta-band {
    padding: 28px;
  }

  /* flex-basis:100% forces the form onto its own line. Without it, basis 0%
     plus min-width 0 means it always "fits" beside the heading, so the flex
     algorithm never wraps and squeezes it to whatever is left over. Between
     roughly 405px and this breakpoint the heading still fits alongside, which
     left the form 10px wide and the field spilling off the right edge. It
     showed on a Pro Max and not on a 402pt phone, where the heading needs the
     whole line anyway. */
  .cta-band .signup {
    flex-basis: 100%;
    min-width: 0;
    max-width: none;
  }

  /* The pair no longer fits on one line at this width. */
  .signup {
    flex-wrap: wrap;
  }

  .signup > .field {
    flex-basis: 100%;
  }

  .signup > .btn {
    width: 100%;
  }
}

/* ---- Sheet -------------------------------------------------------------
   The modal that answers the signup. Follows the system's Sheet: surface
   fill, --radius-lg, --shadow-lg (a genuinely floating surface, the one case
   shadows are allowed), and a semi-transparent teal scrim. */

.sheet {
  width: min(420px, calc(100vw - 40px));
  padding: 32px;
  border: none;
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  color: var(--color-text);
  box-shadow: var(--shadow-lg);
}

/* Custom properties only reach ::backdrop in newer engines, so the literal
   repeats as the var() fallback rather than leaving the scrim to the UA. */
.sheet::backdrop {
  background: var(--color-scrim, rgba(21, 39, 43, 0.55));
}

.sheet__title {
  font: var(--text-display-sm);
  letter-spacing: var(--tracking-display-sm);
  margin: 0 0 12px;
}

.sheet__body {
  font: var(--text-ui-body);
  color: var(--color-text-secondary);
  margin: 0 0 16px;
}

.sheet .btn {
  margin-top: 8px;
}

@media (prefers-reduced-motion: no-preference) {
  .sheet[open] {
    animation: sheet-in var(--duration-base) var(--ease-out);
  }

  .sheet[open]::backdrop {
    animation: scrim-in var(--duration-base) var(--ease-out);
  }
}

@keyframes sheet-in {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
}

@keyframes scrim-in {
  from {
    opacity: 0;
  }
}

/* ---- Scroll reveal -----------------------------------------------------
   The design system's motion budget is the whole spec here: a fade and a
   gentle rise on the system's own easing and longest duration, once per
   element, never replayed on the way back up. No parallax, no scale, no
   ambient loop — this is a low-arousal product and the motion has to stay
   beneath notice.

   Gated on .js, which the inline head script sets before first paint. Without
   JS nothing below is ever applied and the page renders plainly visible. */

.js [data-reveal] {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity var(--duration-slow) var(--ease-out),
    transform var(--duration-slow) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

.js [data-reveal].is-visible {
  opacity: 1;
  transform: none;
}

/* Cards in a row arrive a beat apart, enough to read as one movement rather
   than a grid snapping into place at once. */
.grid-2 > [data-reveal]:nth-child(2),
.grid-3 > [data-reveal]:nth-child(2) {
  --reveal-delay: 70ms;
}

.grid-3 > [data-reveal]:nth-child(3) {
  --reveal-delay: 140ms;
}

/* ---- Motion ------------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  .btn:active {
    transform: none;
  }

  /* Not a faster reveal — no reveal. The content is simply there, whether or
     not the observer ever gets round to it. */
  .js [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ---- Print ------------------------------------------------------------- */

@media print {
  .header__controls,
  .signup,
  .skip-link {
    display: none;
  }

  body {
    background: var(--white);
  }
}
