/* Osso website - tokens from src/theme/index.ts */
/* The [hidden] attribute is only a UA rule of display:none, so any element
   given an explicit display, as .wl-form and .wl-done both are, ignores it and
   stays on screen. The admin console had exactly this bug. */
[hidden] { display: none !important; }
/* The waitlist is the only thing on this page anybody can act on, so it sits
   under the headline rather than after the explanatory cards, and is styled as
   the page's one solid element instead of another cream panel among cream
   panels. */
.waitlist { max-width:420px; width:100%; margin:30px auto 0; }
/* Stacked, not side by side. Two inputs sharing a row left the email field too
   narrow for an ordinary address, which is the one field that must never feel
   cramped. */
.wl-form {
  display:flex; flex-direction:column; gap:10px; padding:16px;
  background:#fff; border:1px solid var(--cream200); border-radius:18px;
  box-shadow:0 12px 34px -20px rgba(12,42,34,.5);
}
/* A visible border rather than a tint: cream on white is almost no contrast,
   so the fields read as flat areas rather than as things to type in. */
/* font-size stays at 16px however short these get: iOS Safari zooms the page
   when a focused input is smaller than that, which throws the whole layout on
   the one device most of these signups will come from. Height comes off the
   padding instead. */
.wl-form input {
  width:100%; padding:11px 15px; border:1.5px solid var(--cream200);
  border-radius:12px; background:var(--cream0); font:inherit; font-size:16px;
  line-height:1.3; color:var(--ink900);
}
/* The placeholder is a single space and is never seen: it exists so
   :placeholder-shown can tell an empty field from a filled one, which is what
   drives the label without any JavaScript. */
.wl-form input::placeholder { color:transparent; }
/* A real <label for>, not a placeholder pretending to be one. A placeholder
   disappears the moment you start typing, so the field you are in stops saying
   what it wants - and screen readers get nothing to announce. This keeps the
   label visible by moving it onto the top border once the field is focused or
   filled. */
.wl-field { position:relative; }
.wl-field label {
  position:absolute; left:11px; top:50%; transform:translateY(-50%);
  padding:0 5px; color:var(--ink500); font-size:16px; line-height:1;
  /* So a click still lands on the input underneath. */
  pointer-events:none;
  transition:top .14s ease, font-size .14s ease, color .14s ease;
}
.wl-field input:focus + label,
.wl-field input:not(:placeholder-shown) + label {
  top:0; font-size:12px; font-weight:700; color:var(--pine700);
  /* Card white, not the field's own fill: raised, the label straddles the
     border, and this is what cuts a gap in it. */
  background:#fff; border-radius:4px;
}
/*
 * The city suggestions, matching the app's address fields rather than the
 * browser's own list.
 *
 * Absolute, for the same reason SuggestionOverlay is in the app: a list that
 * takes part in layout pushes the button below it down the page while you type
 * and pulls it back when you stop, so the thing you were reaching for moves.
 */
.wl-suggest {
  position:absolute; top:calc(100% + 6px); left:0; right:0; z-index:50;
  margin:0; padding:0; list-style:none; overflow:hidden;
  background:#fff; border:1.5px solid var(--cream200); border-radius:12px;
  box-shadow:0 6px 18px rgba(71,57,46,.14);
}
.wl-suggest li {
  padding:11px 14px; font-size:15px; color:var(--ink900); cursor:pointer;
  /* The card centres its text; a list of names reads down its left edge. */
  text-align:left;
}
.wl-suggest li + li { border-top:1px solid var(--cream200); }
.wl-suggest li:hover, .wl-suggest li[aria-selected="true"] { background:var(--cream50); }
.wl-form input:focus {
  outline:none; border-color:var(--pine500); background:#fff;
  box-shadow:0 0 0 3px rgba(30,107,84,.12);
}
/* Narrower than the inputs and centred: the button is the conclusion of the
   form, not another field. */
.wl-form button {
  align-self:center; margin-top:6px; padding:11px 28px; border:0;
  border-radius:999px; background:var(--pine500); color:#fff; font:inherit;
  font-weight:700; font-size:15px; cursor:pointer; transition:background .15s ease;
}
.wl-form button:hover { background:var(--pine600); }
.wl-form button:disabled { opacity:.55; cursor:default; }
/* The password form on the auth callback. Same field treatment as the
   waitlist so the two pages do not look like two different sites, but laid
   out on the page rather than inside a card: it is the whole point of the
   screen, not a footer on it. */
.pw-form { display:flex; flex-direction:column; gap:14px; margin:22px 0 0; max-width:380px; }
.pw-form input {
  width:100%; padding:11px 15px; border:1.5px solid var(--cream200);
  border-radius:12px; background:#fff; font:inherit; font-size:16px;
  line-height:1.3; color:var(--ink900);
}
.pw-form input::placeholder { color:transparent; }
.pw-form .wl-field label { background:var(--cream0); }
.pw-form input:focus {
  outline:none; border-color:var(--pine500); background:#fff;
  box-shadow:0 0 0 3px rgba(30,107,84,.12);
}
.pw-form button {
  align-self:flex-start; margin-top:2px; padding:11px 28px; border:0;
  border-radius:999px; background:var(--pine500); color:#fff; font:inherit;
  font-weight:700; font-size:15px; cursor:pointer;
}
.pw-form button:hover { background:var(--pine600); }
.pw-form button:disabled { opacity:.55; cursor:default; }
/* Show/hide, inside the field so it cannot be mistaken for the submit.
   Selector carries the form class as well: the .pw-form button rule above is
   one specificity point heavier than a bare .pw-peek, and won, so the toggle
   came out as a second green pill sitting inside the input. */
.pw-wrap { position:relative; }
.pw-wrap input { padding-right:82px; }
.pw-form .pw-peek {
  position:absolute; right:6px; top:50%; transform:translateY(-50%);
  margin:0; border:0; background:none; border-radius:8px; padding:6px 8px;
  cursor:pointer; font:inherit; font-size:13px; font-weight:700;
  color:var(--pine700); align-self:auto;
}
.pw-form .pw-peek:hover { background:var(--cream50); color:var(--pine500); }

/* The same four rules the app shows while you choose a password, answered as
   you type. They wrap onto as many lines as the width allows rather than being
   laid out in fixed columns, so a narrow phone stacks them instead of
   scrolling sideways. */
.pw-meter { margin:-2px 0 2px; }
.pw-bars { display:flex; gap:6px; }
.pw-bars span {
  flex:1; height:6px; border-radius:99px; background:var(--cream200);
  transition:background .18s ease;
}
.pw-meter.weak   .pw-bars span.on { background:#a4342b; }
.pw-meter.ok     .pw-bars span.on { background:var(--gold600, #c8912a); }
.pw-meter.strong .pw-bars span.on { background:var(--pine500); }
.pw-reqs {
  display:flex; flex-wrap:wrap; gap:6px 12px; margin-top:8px;
  font-size:12.5px; color:var(--ink500);
}
.pw-reqs [data-strength] { font-weight:700; }
.pw-meter.weak   [data-strength] { color:#a4342b; }
.pw-meter.ok     [data-strength] { color:var(--gold600, #c8912a); }
.pw-meter.strong [data-strength] { color:var(--pine500); }
/* A tick that fills in, rather than an item that appears: the list of what is
   still missing should not move while you are typing into it. */
.pw-reqs [data-req]::before { content:'○ '; }
.pw-reqs [data-req].met { color:var(--pine500); }
.pw-reqs [data-req].met::before { content:'● '; }
.waitlist > h2 { margin:0 0 3px; font-size:19px; letter-spacing:-.01em; }
.waitlist > p { margin:0 0 12px; color:var(--ink700); font-size:14px; }
.wl-msg { margin:14px 2px 0; font-weight:600; font-size:15px; }
.wl-msg.ok { color:var(--pine500); }
.wl-msg.bad { color:#a4342b; }
/* Same box as the form it replaces, so the page does not jump on success. */
.wl-done {
  box-sizing:border-box;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:10px; padding:16px; text-align:center;
  background:#fff; border:1px solid var(--cream200); border-radius:18px;
  box-shadow:0 12px 34px -20px rgba(12,42,34,.5); color:var(--pine500);
}
.wl-done p { margin:0; color:var(--ink700); font-size:15px; font-weight:600; }
.waitlist .note { margin:14px 2px 0; color:var(--ink500); font-size:12.5px; line-height:1.6; text-align:center; }

:root {
  --pine900:#0c2a22; --pine700:#123f32; --pine600:#185241; --pine500:#1e6b54; --pine100:#e3eee9;
  --gold500:#e4b23f; --gold600:#c99320;
  --cream0:#fcfaf5; --cream50:#f8f4ec; --cream200:#e7decf;
  --ink900:#1c2420; --ink700:#35423b; --ink500:#64726a;
  --logo-stroke:var(--pine500); --logo-fill:var(--gold500);
}
* { box-sizing:border-box; }
body {
  margin:0; background:var(--cream0); color:var(--ink900);
  font:16px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  display:flex; flex-direction:column; min-height:100vh;
}
a { color:var(--pine600); }
.muted { color:var(--ink500); }

.topbar {
  display:flex; align-items:center; justify-content:space-between; gap:16px;
  padding:16px 24px; border-bottom:1px solid var(--cream200); background:#fff;
}
.brand { display:flex; align-items:center; gap:10px; font-weight:800; font-size:19px; color:var(--ink900); text-decoration:none; letter-spacing:-.02em; }
.topbar nav { display:flex; gap:18px; font-size:14px; font-weight:600; }
.topbar nav a { text-decoration:none; color:var(--ink500); }
.topbar nav a:hover, .topbar nav a.on { color:var(--pine600); }

main { flex:1; }

/* A native select, so the control is the one the visitor's own device draws
   and there is no menu to keep open, position or close. The arrow is drawn
   here because a bare select on a dark bar shows the platform's own, which is
   black on Windows and invisible against pine900. */
.langpick {
  font:inherit; font-size:14px; font-weight:600; cursor:pointer;
  color:var(--ink700); background-color:transparent;
  border:1px solid var(--cream200); border-radius:999px;
  padding:7px 32px 7px 14px;
  -webkit-appearance:none; appearance:none;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%2364726a' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 12px center; background-size:11px;
}
.langpick:focus-visible { outline:2px solid var(--pine500); outline-offset:2px; }
/* The open menu is drawn by the platform in its own colours, so the options
   have to carry ink of their own or they inherit the bar's cream on white. */
.langpick option { color:var(--ink900); background:#fff; }

/* Says what this page is, once, before anything else. */
.eyebrow {
  margin:0 0 20px; font-size:11px; font-weight:800; letter-spacing:.16em;
  text-transform:uppercase; color:var(--pine600);
  background:var(--pine100); border-radius:999px; padding:6px 14px;
  display:inline-block; align-self:center;
}

/* The hero fills the first screen and centres what is in it, so the one thing
   a visitor can do is on screen without scrolling. The explanatory cards sit
   deliberately below the fold: they answer a question somebody only has after
   the headline has landed. */
.hero-inner {
  max-width:820px; margin:0 auto; padding:28px 24px 56px; text-align:center;
  min-height:calc(100svh - 220px);
  display:flex; flex-direction:column; align-items:center; justify-content:center;
}
.hero h1 { font-size:clamp(32px,5.4vw,54px); line-height:1.06; letter-spacing:-.03em; margin:0 0 20px; }
.hero h1 em { font-style:normal; color:var(--gold600); }
.lead { font-size:17px; line-height:1.55; color:var(--ink700); margin:0 auto; max-width:38ch; }
/* When it opens, said once and said loudly.
   It used to be a pine100 pill under the lede - the same shape, the same fill
   and nearly the same size as the "Wachtlijst" tag above the headline, so the
   two read as a matched pair of labels and neither one carried any weight. It
   is a date, which is the second thing a visitor wants after what this is, so
   it sits directly under the headline in the one colour nothing else here
   uses. */
.tagline {
  margin:0 0 10px; font-size:clamp(18px,2.7vw,24px); font-weight:800;
  letter-spacing:-.015em; color:var(--gold600);
}
.soon {
  margin:0 0 22px; font-size:15px; font-weight:600; color:var(--ink700);
}
/* Above the page's background, whatever it is. */
.topbar, main, .footer { position:relative; z-index:1; }

/*
 * The landing page, dark.
 *
 * The same ground the admin sign-in stands on: two soft radial washes over
 * pine900, one gold high on the right and one pine300 low on the left, so the
 * green has some depth in it rather than reading as a flat fill. Fixed
 * attachment because it is the ground and not an element - it must not slide
 * up as the page scrolls past it.
 *
 * Scoped to body.dark rather than applied to body, because page() also
 * draws the privacy policy, the terms and the delete-account page. Those are
 * documents: a wall of legal text reversed out of dark green is harder to read
 * and looks nothing like the rest of the internet's paperwork.
 */
body.dark {
  color:var(--cream0);
  background:
    radial-gradient(60% 60% at 78% 12%, rgba(228, 178, 63, 0.16), transparent 70%),
    radial-gradient(70% 70% at 12% 88%, rgba(111, 167, 148, 0.18), transparent 70%),
    var(--pine900);
  background-attachment:fixed;
}
/* Pine on pine is invisible: the mark takes the light half of the palette. */
body.dark { --logo-stroke:var(--pine100); }
body.dark a { color:var(--gold500); }
body.dark .muted { color:rgba(227,238,233,.62); }

/* The bar loses its white plank and becomes a rule over the gradient. */
body.dark .topbar { background:transparent; border-bottom:1px solid rgba(227,238,233,.14); }
body.dark .brand { color:var(--cream0); }
body.dark .langpick {
  color:var(--cream0); border-color:rgba(227,238,233,.28);
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%23e3eee9' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
}

body.dark .eyebrow { background:rgba(227,238,233,.12); color:rgba(227,238,233,.82); }
body.dark .hero h1 { color:var(--cream0); }
/* gold600 is mixed for cream; on pine900 it wants the brighter step. */
body.dark .hero h1 em, body.dark .tagline { color:var(--gold500); }
body.dark .soon { color:rgba(227,238,233,.78); }
body.dark .lead { color:rgba(227,238,233,.78); }
body.dark .note, body.dark .waitlist .note { color:rgba(227,238,233,.6); }

/* Glass rather than white: two solid white panels this far down the page would
   pull the eye off the form, which is the only thing here anybody can do. */
body.dark .cards article { background:rgba(227,238,233,.07); border-color:rgba(227,238,233,.14); }
body.dark .cards h2 { color:var(--cream0); }
body.dark .cards p { color:rgba(227,238,233,.7); }

body.dark .footer { background:transparent; border-top:1px solid rgba(227,238,233,.14); }

.cards { display:grid; grid-template-columns:repeat(auto-fit,minmax(260px,1fr)); gap:16px; margin:88px 0 0; text-align:left; width:100%; }
.cards article { background:#fff; border:1px solid var(--cream200); border-radius:16px; padding:22px; }
.cards h2 { margin:0 0 6px; font-size:18px; letter-spacing:-.01em; }
.cards p { margin:0; color:var(--ink500); font-size:15px; }
.note { margin-top:34px; color:var(--ink500); font-size:14px; }

.prose { max-width:760px; margin:0 auto; padding:0 24px 72px; }
.doc h1 { font-size:clamp(28px,4vw,38px); letter-spacing:-.02em; margin:28px 0 4px; }
.doc h2 { font-size:17px; margin:28px 0 6px; letter-spacing:-.01em; }
.doc p { margin:0 0 4px; color:var(--ink700); }
.updated { color:var(--ink500); font-size:14px; }
.doc .lead { margin:16px 0 8px; max-width:none; }
.disclaimer {
  /* Well clear of the paragraph above it: it is an aside at the end of the
     page, and at 36px it read as the next section of the same argument. */
  margin-top:64px; padding:14px 16px; border-radius:12px;
  background:var(--cream50); border:1px solid var(--cream200);
  color:var(--ink500); font-size:14px;
}

.footer { border-top:1px solid var(--cream200); background:#fff; }
.footer-inner { max-width:820px; margin:0 auto; padding:26px 24px; text-align:center; font-size:14px; }
.footer-inner p { margin:0 0 6px; }
/* "Account verwijderen" is one link and has to wrap as one. Without this the
   line breaks between the two words on a narrow screen, so the footer reads as
   four links, one of them called "Account" and one called "verwijderen". */
.footer-inner a { white-space:nowrap; }

@media (prefers-reduced-motion:no-preference) { html { scroll-behavior:smooth; } }
