/* ==========================================================================
   Landing page — layered on top of tools.css, which owns every colour token,
   the top bar, buttons and the footer. Nothing here redefines a token.
   ========================================================================== */

/* ---------- Google sign-in button ----------------------------------------
   Google's own pattern: white surface, full-colour G in its own well, one
   clear label. Kept white in both themes — a recoloured Google button reads
   as a knock-off, and this is the one control on the page that has to look
   like exactly what it is.
   ------------------------------------------------------------------------- */
.gbtn {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 6px 22px 6px 6px;
  border-radius: var(--r-pill);
  background: #fff;
  color: #1f1f1f;
  text-decoration: none;
  font-family: var(--font);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  border: 1px solid rgba(0, 0, 0, 0.08);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.24), 0 0 0 0 rgba(247, 166, 0, 0);
  cursor: pointer;
  transition: transform var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease),
              background var(--dur) var(--ease);
}
.gbtn:hover {
  background: #fff;
  transform: translateY(-1px);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.34), 0 0 0 4px rgba(247, 166, 0, 0.16);
}
.gbtn:active { transform: translateY(0) scale(0.99); }
.gbtn:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* The logo sits in its own white well, which is what stops the multicolour
   mark from vibrating against the button surface at small sizes. */
.gbtn-logo {
  display: grid;
  place-items: center;
  width: 34px; height: 34px;
  border-radius: 50%;
  background: #fff;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.07);
  flex-shrink: 0;
}
.gbtn-logo svg { width: 18px; height: 18px; display: block; }
.gbtn-label { white-space: nowrap; }

/* On the light canvas a white button on near-white needs a real edge, and the
   dark-theme drop shadow does nothing for it. */
:root[data-theme="light"] .gbtn {
  border-color: rgba(0, 0, 0, 0.16);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
:root[data-theme="light"] .gbtn:hover {
  border-color: rgba(0, 0, 0, 0.24);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.12), 0 0 0 4px rgba(247, 166, 0, 0.18);
}

.gbtn-sm {
  gap: 9px;
  padding: 4px 16px 4px 4px;
  font-size: 0.85rem;
}
.gbtn-sm .gbtn-logo { width: 26px; height: 26px; }
.gbtn-sm .gbtn-logo svg { width: 15px; height: 15px; }

/* ---------- Apple sign-in button ------------------------------------------
   Same geometry as the Google button. Apple's guidelines allow the mark in
   black on white or white on black and nothing in between, and the background
   decides which: a white button on a dark page, a black one on a light page.
   So it inverts with the theme, where the Google button stays white in both.
   ------------------------------------------------------------------------- */
.abtn {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 6px 22px 6px 6px;
  border-radius: var(--r-pill);
  background: #fff;
  color: #1f1f1f;
  text-decoration: none;
  font-family: var(--font);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  border: 1px solid rgba(0, 0, 0, 0.08);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.24);
  cursor: pointer;
  transition: transform var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease),
              background var(--dur) var(--ease);
}
.abtn:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.34), 0 0 0 4px rgba(247, 166, 0, 0.16);
}
.abtn:active { transform: translateY(0) scale(0.99); }
.abtn:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.abtn-logo {
  display: grid;
  place-items: center;
  width: 34px; height: 34px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.06);
  flex-shrink: 0;
}
.abtn-logo svg { width: 19px; height: 19px; display: block; }

/* On the light canvas it is the black button — the same rule read the other
   way round. */
:root[data-theme="light"] .abtn {
  background: #000;
  color: #fff;
  border-color: rgba(0, 0, 0, 0.16);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
:root[data-theme="light"] .abtn-logo { background: rgba(255, 255, 255, 0.14); }
:root[data-theme="light"] .abtn:hover {
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.22), 0 0 0 4px rgba(247, 166, 0, 0.18);
}

.abtn-sm {
  gap: 9px;
  padding: 4px 16px 4px 4px;
  font-size: 0.85rem;
}
.abtn-sm .abtn-logo { width: 26px; height: 26px; }
.abtn-sm .abtn-logo svg { width: 16px; height: 16px; }

/* ---------- the sign-in page ---------- */
.signin-wrap {
  max-width: 460px;
  margin: 0 auto;
  padding: 8vh 0 12vh;
  text-align: center;
}
.signin-wrap h1 {
  font-size: 1.7rem;
  letter-spacing: -0.02em;
  margin: 0 0 8px;
}
.signin-wrap .signin-lede {
  color: var(--fg-dim);
  margin: 0 0 26px;
  line-height: 1.55;
}
.signin-choices {
  display: flex;
  flex-direction: column;
  gap: 12px;
  align-items: stretch;
}
/* Full-width and equal, so neither provider is the recommended one. */
.signin-choices .gbtn,
.signin-choices .abtn { justify-content: center; padding-right: 6px; }
.signin-note {
  margin-top: 22px;
  font-size: 0.82rem;
  color: var(--fg-faint);
  line-height: 1.6;
}

/* ---------- plan buttons ---------- */
.btn-block { display: flex; width: 100%; justify-content: center; }

.btn-cta {
  padding: 13px 24px;
  font-size: 0.94rem;
  font-weight: 600;
  border-radius: var(--r-md);
  gap: 8px;
}
.btn-cta:hover { transform: translateY(-1px); }

/* "Start free" — deliberately quieter than the premium call to action, but
   still clearly a button rather than a link. */
.btn-outline {
  background: transparent;
  border: 1px solid var(--border-strong);
  color: var(--fg);
}
.btn-outline:hover {
  background: var(--surface-2);
  border-color: var(--accent);
  color: var(--fg);
}
.btn-arrow {
  width: 16px; height: 16px;
  flex-shrink: 0;
  transition: transform var(--dur) var(--ease);
}
.btn-outline:hover .btn-arrow { transform: translateX(3px); }

/* Inside a plan card the call to action is scaled down with the card — the
   hero keeps the full-size button. */
.ll-plan .btn-cta {
  padding: 10px 18px;
  font-size: 0.875rem;
  box-shadow: var(--shadow-sm);
}
.ll-plan.is-featured .btn-cta { box-shadow: 0 4px 14px rgba(247, 166, 0, 0.20); }

/* An error banner reuses .banner's box and only recolours it. */
.banner-err {
  border-color: rgba(239, 69, 74, 0.35);
  background: rgba(239, 69, 74, 0.08);
  color: var(--fg);
}
.banner-err .banner-icon { color: var(--neg); }

/* ---------- hero ----------
   The same card the signed-in overview opens on: a 22px surface plate on the
   canvas, an eyebrow, one sentence at display size with its second half in the
   accent, the four numbers that matter, and the phase ribbon. Deliberately not
   a centred marketing hero — the product is a desk, and the front page should
   look like one. */
.ll-hero {
  position: relative;
  overflow: hidden;
  margin: clamp(18px, 3vw, 30px) 0 0;
  padding: clamp(24px, 4vw, 34px) clamp(20px, 4vw, 36px);
  border-radius: 22px;
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-lg);
}
.ll-hero-top {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px 40px;
}
.ll-hero-copy { flex: 1 1 430px; min-width: 0; }

.ll-eyebrow {
  font-size: 11.5px; font-weight: 640;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--fg-faint);
}
.ll-title {
  margin: 10px 0 0;
  font-size: clamp(28px, 4.4vw, 46px);
  line-height: 1.05;
  font-weight: 660;
  letter-spacing: -0.04em;
  max-width: 20ch;
  text-wrap: pretty;
}
.ll-title em { font-style: normal; color: var(--accent); }
/* The accent half is its own clause and reads best on its own line, but a hard
   break is wrong once the line no longer fits anyway — below this width the
   natural wrap is kinder than a break in a fixed place. */
@media (max-width: 720px) { .ll-title-br { display: none; } }
.ll-lede {
  margin: 14px 0 0;
  font-size: 15px;
  line-height: 1.6;
  color: var(--fg-dim);
  max-width: 58ch;
  text-wrap: pretty;
}
.ll-lede b { color: var(--fg); font-weight: 600; }

.ll-hero-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 22px 0 0;
}

/* Label / value rows, the same shape the app's overview uses. */
.ll-hero-stats {
  flex: 0 1 290px;
  display: grid;
  gap: 10px;
  align-content: end;
}
.ll-hero-stat {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding-bottom: 9px;
  border-bottom: 1px solid var(--border);
}
.ll-hero-stat span { font-size: 12.5px; color: var(--fg-dim); }
.ll-hero-stat b {
  font-size: 17px; font-weight: 620;
  font-variant-numeric: tabular-nums;
}
.ll-hero-stat b.up { color: var(--pos); }
.ll-hero-stat b.down { color: var(--neg); }

/* Provenance for the four numbers above: which day's close they are and where
   it came from. Rendered in every state — bundled or live — so the line never
   appears late and shoves the ribbon down the page. */
.ll-hero-asof {
  margin-top: -2px;
  font-size: 11.5px;
  color: var(--fg-faint);
}

/* ---------- phase ribbon ----------
   Markup and renderer are shared with the app (renderPhaseRibbon in chart.js),
   so these rules mirror the ones in desk.css. They are repeated rather than
   hoisted because desk.css is not served to signed-out visitors. */
.ribbon-wrap { margin: 26px 0 0; }
.ribbon {
  display: flex;
  height: 12px;
  border-radius: var(--r-pill);
  overflow: hidden;
  border: 1px solid var(--border);
}
.ribbon i { display: block; }

.ribbon-mark { position: relative; height: 34px; }
.ribbon-today {
  position: absolute;
  top: 0;
  display: grid;
  justify-items: end;
  gap: 3px;
  transform: translateX(-100%);
}
.ribbon-today i {
  display: block;
  width: 2px; height: 10px;
  margin-right: 5px;
  background: var(--fg);
}
.ribbon-today span {
  font-size: 11px; font-weight: 600;
  padding: 2px 8px;
  border-radius: var(--r-pill);
  background: var(--fg);
  color: var(--bg);
  white-space: nowrap;
}
.ribbon-key { display: flex; gap: 14px; flex-wrap: wrap; }
.ribbon-key span {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 12px; color: var(--fg-dim);
}
.ribbon-key i { width: 9px; height: 9px; border-radius: 3px; }

/* ---------- the chart stage ---------- */
.ll-stage {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 22px;
  padding: clamp(12px, 2vw, 18px);
  box-shadow: var(--shadow-sm);
}

.ll-chart-host { position: relative; }
.ll-chart-host svg {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--r-lg);
}

/* ---------- chart internals ---------- */
.ll-gridline {
  stroke: var(--border);
  stroke-width: 1;
  stroke-dasharray: 2 5;
}
.ll-gridlabel,
.ll-ticklabel {
  fill: var(--fg-faint);
  font-family: var(--font-num);
  font-size: 10.5px;
}
.ll-ticklabel { text-anchor: middle; }

.ll-line {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.1;
  stroke-linejoin: round;
  stroke-linecap: round;
}
.ll-area {
  fill: var(--accent);
  opacity: 0.07;
  stroke: none;
}

/* The trend channel — the log-linear fit through every month close, with the
   widest run either side of it drawn as the channel walls. Quiet: it is the
   backdrop the price line is read against, not a second series. */
.ll-trend-edge {
  fill: none;
  stroke: var(--fg-faint);
  stroke-width: 1;
  stroke-dasharray: 5 6;
  opacity: 0.55;
}
.ll-trend-mid {
  fill: none;
  stroke: var(--fg-faint);
  stroke-width: 1;
  stroke-dasharray: 2 6;
  opacity: 0.4;
}

/* cycle extremes — dots only; the dated read-out lives in the app's tool 1 */
.ll-event-dot {
  fill: var(--bg);
  stroke-width: 2;
}
.ll-event-dot.is-top    { stroke: var(--neg); }
.ll-event-dot.is-bottom { stroke: var(--pos); }

/* where the line ends */
.ll-now-dot {
  fill: var(--accent);
  stroke: var(--surface);
  stroke-width: 2.4;
}
.ll-now-label {
  fill: var(--accent);
  font-family: var(--font-num);
  font-size: 11px;
  font-weight: 700;
}

.ll-foot {
  margin: 14px 2px 2px;
  font-size: 0.78rem;
  line-height: 1.6;
  color: var(--fg-faint);
}
.ll-foot b { color: var(--fg-dim); }
.ll-foot-dim { display: block; margin-top: 4px; opacity: 0.8; }

/* ---------- sections ---------- */
.ll-section { padding: clamp(30px, 5vw, 52px) 0 0; }

/* A quiet uppercase label with a dim note opposite, the way the app's overview
   heads its card grid — the page is a desk, not a brochure, so the section
   headings stop competing with the one headline that matters. */
.ll-sec-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin: 0 0 12px;
}
.ll-sec-head h3 {
  margin: 0;
  font-size: 13px; font-weight: 640;
  letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--fg-faint);
}
.ll-sec-head p {
  margin: 0;
  font-size: 12.5px; color: var(--fg-faint);
  text-align: right;
}
@media (max-width: 560px) {
  /* The note is context, not content — drop it before it wraps under the head. */
  .ll-sec-head p { display: none; }
}

/* ---------- tool cards ----------
   The app's overview card, minus the live number a signed-out visitor has no
   right to: number badge, the tool's name in small caps, then the one question
   it answers as the headline. The question is the reason to click; "Historic
   returns" is not. */
.ll-tools {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 14px;
}
.ll-tool {
  display: grid;
  gap: 10px;
  align-content: start;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 18px 20px;
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.ll-tool:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-lg);
  border-color: var(--border-strong);
}
@media (prefers-reduced-motion: reduce) {
  .ll-tool, .ll-tool:hover { transition: none; transform: none; }
}

.ll-tool-head { display: flex; align-items: center; gap: 9px; }
.ll-tool-n {
  width: 20px; height: 20px; flex: none;
  display: grid; place-items: center;
  border-radius: var(--r-xs);
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 10.5px; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
/* Pattern Labs carries a count, not an index — two digits need the room. */
.ll-tool-n { padding: 0 4px; width: auto; min-width: 20px; }
.ll-tool-kind {
  flex: 1; min-width: 0;
  font-size: 12px; font-weight: 600;
  letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--fg-faint);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ll-tool-q {
  margin: 0;
  font-size: 16px; font-weight: 580;
  letter-spacing: -0.02em;
  text-wrap: pretty;
}
.ll-tool p {
  margin: 0;
  font-size: 13px; line-height: 1.6;
  color: var(--fg-dim);
  text-wrap: pretty;
}

.ll-badge {
  flex: none;
  padding: 2px 9px;
  border-radius: var(--r-pill);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.ll-badge-free { background: rgba(32, 178, 108, 0.14); color: var(--pos); }
.ll-badge-prem { background: var(--accent-soft); color: var(--accent); }

/* ---------- plans ----------
   Sized to the tool cards above them rather than to a pricing page: the same
   13px body type, the same padding, a price that reads as a number in a desk
   rather than a billboard. Two compact cards, side by side, and the pair is
   narrower than the tool grid so it reads as a footnote to the product. */
.ll-plans {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(232px, 1fr));
  /* Each card hugs its own content rather than stretching to its neighbour —
     a short Trial card under a taller Premium one reads as the smaller offer,
     and stops the free card ending in 60px of empty white. */
  align-items: start;
  gap: 14px;
  max-width: 620px;
}
.ll-plan {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 16px 16px 15px;
  box-shadow: var(--shadow-sm);
}
.ll-plan.is-featured {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent-soft), var(--shadow-sm);
}

/* Name and price on one line — the two cards then agree on a single baseline
   whatever the price string is, and the card loses a whole stacked row. */
.ll-plan-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}
.ll-plan-name {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  font-weight: 640;
  color: var(--fg-faint);
}
.ll-plan.is-featured .ll-plan-name { color: var(--accent); }

/* Tabular figures, like every other number in the product — €4.99 and Free
   should sit on the same baseline grid as the readings the app prints. */
.ll-plan-price {
  font-size: 21px;
  font-weight: 650;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.ll-plan-per {
  font-size: 12px;
  font-weight: 500;
  color: var(--fg-faint);
  margin-left: 4px;
  letter-spacing: normal;
}

/* The billing period, spelled out rather than left to a "/mo" abbreviation. */
.ll-plan-billing {
  margin: 3px 0 12px;
  font-size: 11.5px;
  color: var(--fg-faint);
}
.ll-plan-list {
  list-style: none;
  margin: 0 0 14px;
  padding: 0;
  flex: 1;
  border-top: 1px solid var(--border);
  padding-top: 11px;
}
.ll-plan-list li {
  position: relative;
  padding: 3px 0 3px 19px;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--fg-dim);
}
.ll-plan-list li::before {
  position: absolute;
  left: 0;
  font-size: 11px;
  font-weight: 700;
}
.ll-plan-list li.yes { color: var(--fg); }
.ll-plan-list li.yes::before { content: '✓'; color: var(--pos); }
.ll-plan-list li.no::before  { content: '✕'; color: var(--fg-faint); }

/* The premium card lists what the free one does not have as one summary line
   instead of seven crossed-off rows — the same information, a third of the
   card height, and it stops the pair reading as a wall of ticks. */
.ll-plan-more {
  margin: -6px 0 14px;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--fg-faint);
}

/* ---------- narrow screens ---------- */
@media (max-width: 620px) {
  .ll-hero { border-radius: var(--r-xl); }
  .ll-hero-stats { flex: 1 1 100%; }
  .ll-hero-cta .btn-cta { flex: 1 1 100%; justify-content: center; }
  .ll-tools { grid-template-columns: minmax(0, 1fr); }
}
