/* ==========================================================================
   Flowtent landing — styles.

   Tokens are the light half of mockups/flowtent-design/project/assets/
   flowtent-tokens.css, trimmed to what this page uses. The dark palette is
   deliberately NOT here: the landing was designed light-only (the editor
   section carries its own hardcoded dark treatment), so shipping the dark
   overrides would style half a page nobody designed.

   `color-scheme: light` is set for the same reason. The token file's
   `@media (prefers-color-scheme: dark) { :root:not([data-theme]) }` block
   sets `color-scheme: dark` — on a page that never sets data-theme, that
   leaves the layout light while the browser paints form controls dark. The
   email input is the one control on this page, so that would have been
   visible on exactly the element that matters most.
   ========================================================================== */

/* ---- Self-hosted fonts ------------------------------------------------
   Public Sans ships as ONE variable file per subset covering 400–800, which
   is every weight this page uses. Five static weights would have been five
   downloads. latin-ext is not optional here — it carries ą ć ę ł ń ó ś ź ż.  */

@font-face {
  font-family: 'Public Sans';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/public-sans-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Public Sans';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/public-sans-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/ibm-plex-mono-400-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/ibm-plex-mono-400-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---- Tokens ------------------------------------------------------------ */

:root {
  color-scheme: light;

  --ft-bg: #F6F7F9;
  --ft-surface: #FFFFFF;
  --ft-surface-2: #F1F3F6;
  --ft-hairline: #E3E7EC;
  /* --ft-text-4 is a DECORATION token, not a text token: SVG strokes, dashed
     outlines, hairlines. At 2.28:1 on --ft-bg it fails WCAG AA by a wide
     margin, so anything a reader has to read stops at --ft-text-3.
     Darkening text-4 instead would have to take it all the way down to
     text-3 to pass, collapsing two rungs of the tonal ladder into one.
     text-3 itself sat at 4.53:1 -- a pass by three hundredths; #5F6C78
     buys 5.0:1 for a shift nobody can see. */
  --ft-text-1: #1B2733;
  --ft-text-2: #46545F;
  --ft-text-3: #5F6C78;
  --ft-text-4: #9AA7B4;

  --ft-accent: #7C5CFC;
  --ft-accent-strong: #6843FC;
  --ft-accent-text: #5025FB;
  --ft-accent-tint: #EFEAFE;
  --ft-on-accent: #FFFFFF;
  --ft-focus-ring: #7C5CFC;

  --ft-success-tint: #E1F5EA;  --ft-success-deep: #166B3F;
  --ft-warning-tint: #FCF0DA;  --ft-warning-deep: #7A5300;
  --ft-danger-tint:  #FBE9E9;  --ft-danger-deep:  #AE2A24;

  --ft-st-idea-tint: #ECF0F3;      --ft-st-idea-deep: #45525D;
  --ft-st-planned-tint: #E2F1FD;   --ft-st-planned-deep: #0A5FA3;
  --ft-st-progress-tint: #E9EAFC;  --ft-st-progress-deep: #4438C2;
  --ft-st-pending-tint: #FAE7FA;   --ft-st-pending-deep: #9D1FAC;
  --ft-st-published-tint: #DFF3E7; --ft-st-published-deep: #0E7244;

  --ft-brand-instagram: #E1306C; --ft-brand-facebook: #1877F2;
  --ft-brand-linkedin: #0A66C2;  --ft-brand-youtube: #FF0000;
  --ft-brand-tiktok: #FE2C55;    --ft-brand-x: #1DA1F2;
  --ft-brand-snapchat: #F4B400;

  --ft-font: 'Public Sans', -apple-system, 'Segoe UI', sans-serif;
  --ft-font-mono: 'IBM Plex Mono', ui-monospace, monospace;
  --ft-type-body-lg: 400 16px/26px var(--ft-font);
  --ft-type-body: 400 14px/22px var(--ft-font);
  --ft-type-small: 400 13px/20px var(--ft-font);
  --ft-type-micro: 500 12px/16px var(--ft-font);
  --ft-type-mono: 400 12.5px/20px var(--ft-font-mono);

  --ft-r-sm: 6px;  --ft-r-md: 10px;  --ft-r-lg: 14px;
  --ft-r-xl: 20px; --ft-r-full: 999px;
  --ft-shadow-sm: 0 1px 2px rgba(23,36,49,.06);
  --ft-shadow-md: 0 2px 8px -2px rgba(23,36,49,.10), 0 1px 2px rgba(23,36,49,.05);
  --ft-shadow-lg: 0 8px 24px -6px rgba(23,36,49,.14);
  --ft-shadow-overlay: 0 16px 48px -8px rgba(23,36,49,.22);
  --ft-border: 1px solid var(--ft-hairline);

  --ft-nav-h: 60px;
}

/* ---- Base -------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--ft-bg);
  font: var(--ft-type-body);
  color: var(--ft-text-1);
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}

a { color: var(--ft-accent-text); text-decoration: none; }
a:hover { text-decoration: underline; }

/* Every interactive element keeps a visible ring. The prototype had none —
   `outline: none` on the email field with only a box-shadow to replace it,
   which disappears for anyone using forced colours. */
:focus-visible {
  outline: 2px solid var(--ft-focus-ring);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Anchor targets clear the fixed 60px bar. Without this every in-page link
   lands with its heading hidden underneath the nav. */
[id] { scroll-margin-top: calc(var(--ft-nav-h) + 16px); }

.lp-skip {
  position: absolute;
  left: -9999px;
  top: 8px;
  z-index: 300;
}
.lp-skip:focus {
  left: 8px;
  background: var(--ft-surface);
  color: var(--ft-text-1);
  border: var(--ft-border);
  border-radius: var(--ft-r-md);
  padding: 10px 16px;
  font: 600 14px/20px var(--ft-font);
  box-shadow: var(--ft-shadow-md);
  text-decoration: none;
}

.lp-sr {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---- Animations -------------------------------------------------------- */

@keyframes ft-float  { 0%, 100% { transform: translateY(0); }     50% { transform: translateY(-8px); } }
@keyframes ft-float2 { 0%, 100% { transform: translateY(-5px); }  50% { transform: translateY(5px); } }
@keyframes ft-toast-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes ft-pulse  { 0%, 100% { opacity: .5; } 50% { opacity: 1; } }
@keyframes ft-clock  { to { transform: rotate(360deg); } }
/* Both ends of ft-alarm are legible -- 6.1:1 and 6.9:1. The illegible part was
   the journey: interpolating foreground and background at once passes through
   #aa915c on #cdb88c, which is 1.56:1, and that is the frame the contrast audit
   caught. steps(1, end) removes the interpolation entirely, so the badge snaps
   between two legible states. An alarm that blinks rather than cross-fades is
   also closer to what an alarm looks like. */
@keyframes ft-alarm  { 0%, 100% { background: var(--ft-warning-tint); color: var(--ft-warning-deep); animation-timing-function: steps(1, end); }
                       50%      { background: var(--ft-warning-deep); color: #FFFFFF; animation-timing-function: steps(1, end); } }

/* ---- Layout ------------------------------------------------------------ */

.lp-wrap { max-width: 1200px; margin: 0 auto; padding-left: 28px; padding-right: 28px; }

.lp-nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;
  display: flex; align-items: center; gap: 22px;
  height: var(--ft-nav-h); padding: 0 28px;
  background: transparent; border-bottom: 1px solid transparent;
  backdrop-filter: blur(12px);
  transition: background 160ms, border-color 160ms;
}
.lp-nav[data-solid] { background: rgba(255,255,255,.86); border-bottom-color: var(--ft-hairline); }

.lp-navlinks a { font: 500 13px/18px var(--ft-font); color: var(--ft-text-2); padding: 8px 12px; border-radius: var(--ft-r-md); white-space: nowrap; transition: background 120ms; }
.lp-navlinks a:hover { background: var(--ft-surface-2); text-decoration: none; }

.lp-h1 { font: 800 52px/60px var(--ft-font); letter-spacing: -0.025em; margin: 14px 0 0; text-wrap: pretty; }
.lp-h2 { font: 700 34px/42px var(--ft-font); letter-spacing: -0.02em; margin: 10px 0 0; text-wrap: pretty; }
.lp-eyebrow { font: 600 13px/18px var(--ft-font); color: var(--ft-accent-text); }
.lp-lead { font: var(--ft-type-body-lg); color: var(--ft-text-2); text-wrap: pretty; }

.lp-card { background: var(--ft-surface); border: var(--ft-border); border-radius: var(--ft-r-lg); padding: 22px; }
.lp-card-hover { transition: box-shadow 160ms cubic-bezier(.2,.6,.2,1), transform 160ms cubic-bezier(.2,.6,.2,1); }
.lp-card-hover:hover { box-shadow: var(--ft-shadow-md); transform: translateY(-2px); }

.lp-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  background: var(--ft-accent-strong); color: var(--ft-on-accent);
  border: none; border-radius: var(--ft-r-md);
  padding: 13px 22px; font: 600 15px/22px var(--ft-font);
  cursor: pointer; white-space: nowrap;
  transition: filter 120ms, transform 120ms;
}
.lp-btn:hover { filter: brightness(1.1); }
.lp-btn:active { transform: translateY(1px); }
.lp-btn[disabled] { opacity: .85; cursor: wait; }

.lp-pill {
  display: inline-flex; align-items: center; gap: 6px;
  border-radius: var(--ft-r-full); padding: 4px 11px 4px 8px;
  font: var(--ft-type-micro);
}

.lp-form { display: flex; gap: 10px; max-width: 460px; }
.lp-form input {
  flex: 1; min-width: 0;
  border: var(--ft-border); border-radius: var(--ft-r-md);
  padding: 13px 16px; font: var(--ft-type-body-lg);
  color: var(--ft-text-1); background: var(--ft-surface);
  transition: border-color 120ms, box-shadow 120ms;
}
.lp-form input:focus { border-color: var(--ft-accent); box-shadow: 0 0 0 3px var(--ft-accent-tint); outline: none; }
.lp-form input:focus-visible { outline: 2px solid var(--ft-focus-ring); outline-offset: 1px; }
.lp-form[data-invalid] input { border-color: var(--ft-danger-deep); }

/* Platform badges. These were tabs; switching one changed a label, a dot and
   nothing else the eye could use, which reads as a control that does not work.
   The list of supported platforms is a fact about the product, so it is now
   stated rather than operated. Same shape as the format tabs below, minus every
   affordance — no pointer cursor, no hover, no selected state. */
.lp-badges { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin: 28px 0 0; padding: 0; list-style: none; }
.lp-badge {
  display: inline-flex; align-items: center; gap: 7px;
  font: 600 13px/18px var(--ft-font); padding: 8px 14px;
  border-radius: var(--ft-r-full);
  border: 1px solid var(--ft-hairline); background: var(--ft-surface); color: var(--ft-text-2);
}

.lp-fmt {
  font: 500 12px/16px var(--ft-font); padding: 5px 12px;
  cursor: pointer; border-radius: var(--ft-r-full); border: none;
  background: var(--ft-surface-2); color: var(--ft-text-2);
  transition: background 120ms;
}
.lp-fmt[aria-selected="true"] { background: var(--ft-accent-strong); color: var(--ft-on-accent); }

/* Preview row: phone in the middle of the PAGE, checks to its right.
   Three tracks rather than two, because a two-track layout centres the pair
   and the phone drifts left of centre. The empty first track mirrors the
   panel's, so the middle one lands on the page axis. */
.lp-preview-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: start;
  gap: 28px;
  margin-top: 26px;
}
.lp-preview-row > #preview { justify-self: center; }

.lp-preflight { justify-self: start; max-width: 320px; }

/* One check per row. Side by side they read as a wrapped sentence; stacked,
   each is a separate verdict — which is what they are. */
.lp-preflight ul {
  display: flex; flex-direction: column; align-items: flex-start;
  gap: 8px; margin: 12px 0 0; padding: 0; list-style: none;
}
/* The panel is narrow, so the longest check wraps to two lines. Without this
   the icon is the flex item that gives way and collapses to a sliver. */
.lp-preflight .lp-pill { max-width: 100%; align-items: flex-start; }
.lp-preflight .lp-pill svg { flex-shrink: 0; margin-top: 2px; }

@media (max-width: 900px) {
  .lp-preview-row { grid-template-columns: minmax(0, 1fr); justify-items: center; }
  .lp-preview-spacer { display: none; }
  .lp-preflight { justify-self: center; max-width: min(420px, 100%); }
}

/* FAQ — native <details>. The chevron is drawn in CSS so the accordion needs
   no script at all; `list-style: none` plus the ::-webkit-details-marker reset
   removes the platform triangle without removing the control. */
.lp-faq details { border-bottom: var(--ft-border); }
.lp-faq summary {
  display: flex; align-items: center; gap: 12px;
  padding: 16px 4px; cursor: pointer;
  font: 600 15px/22px var(--ft-font); color: var(--ft-text-1);
  list-style: none;
}
.lp-faq summary::-webkit-details-marker { display: none; }
.lp-faq summary::after {
  content: ''; margin-left: auto; flex-shrink: 0;
  width: 16px; height: 16px;
  background: currentColor; color: var(--ft-text-3);
  transition: transform 160ms;
  -webkit-mask: no-repeat center / 16px url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7 10l5 5 5-5z'/%3E%3C/svg%3E");
  mask: no-repeat center / 16px url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7 10l5 5 5-5z'/%3E%3C/svg%3E");
}
.lp-faq details[open] summary::after { transform: rotate(180deg); }
.lp-faq summary:focus-visible { outline: 2px solid var(--ft-focus-ring); outline-offset: -2px; border-radius: 4px; }
.lp-faq details p {
  font: var(--ft-type-body-lg); color: var(--ft-text-2);
  margin: 0; padding: 0 28px 18px 4px; text-wrap: pretty;
}

/* Scroll reveal. Elements start visible and are hidden by script only when
   motion is allowed — so with JavaScript off, or reduced motion on, the page
   is simply there. The prototype hid them in CSS and relied on script to
   reveal, which is a blank page for a crawler that does not run scripts. */
[data-reveal] { transition: opacity 480ms cubic-bezier(0,.4,.1,1), transform 480ms cubic-bezier(0,.4,.1,1); }
[data-reveal][data-hidden] { opacity: 0; transform: translateY(22px); }

/* ---- Responsive -------------------------------------------------------- */

/* The week mock is a seven-track grid whose day cells carry nowrap labels
   ("B2B biura", "5 bledow"). Grid items default to min-width: auto, which
   resolves to min-content, so each label became its track's floor: seven of
   them summed to 534px and dragged the whole document to 600px wide on a
   375px screen. The symptom looked like a broken calendar; the cause was that
   every section below it inherited a sideways scroll. min-width: 0 lets each
   track take its 1fr share and clip the label instead of growing for it. */
.lp-week > * { min-width: 0; }

/* Same reasoning, applied to every grid this page lays out. A grid item's
   min-width defaults to auto, which is a min-content floor, so one long word
   or one nowrap label in any cell silently widens the whole track -- and with
   it the document, and with it every section below. These containers all
   collapse to a single column on narrow screens, where that floor is exactly
   what you do not want. Measured at 320px before this rule: .lp-2col needed
   291px inside 280, .lp-flow needed 299. */
.lp-2col > *, .lp-flow > *, .lp-steps > *, .lp-cards3 > *, .lp-studio > * { min-width: 0; }

@media (max-width: 1060px) {
  .lp-hero { grid-template-columns: 1fr !important; gap: 48px !important; }
  /* width: 100% is load-bearing, not decoration. `margin: 0 auto` makes both
     inline margins automatic, and a grid item with an auto margin in an axis
     opts out of stretch in that axis -- so this box stopped filling its track
     and shrank to fit-content, 211px inside a 335px column, dragging the
     layered cards inside it into each other. A definite width leaves the auto
     margins nothing to distribute, and max-width still centres it on tablets. */
  .lp-hero-visual { max-width: 620px; margin: 0 auto; width: 100%; }
  .lp-steps { grid-template-columns: 1fr 1fr !important; }
  .lp-studio { grid-template-columns: 1fr !important; }
  .lp-2col { grid-template-columns: 1fr !important; }
  .lp-flow { grid-template-columns: 1fr !important; }
  .lp-flow-arrow { transform: rotate(90deg); justify-self: center; }
}
@media (max-width: 1000px) { .lp-navlinks { display: none !important; } }
@media (max-width: 700px) {
  .lp-steps, .lp-cards3 { grid-template-columns: 1fr !important; }
  .lp-h1 { font-size: 38px !important; line-height: 46px !important; }
  .lp-h2 { font-size: 26px !important; line-height: 34px !important; }
  .lp-wrap { padding-left: 20px !important; padding-right: 20px !important; }
  .lp-form { flex-direction: column !important; }
  .lp-form input { width: 100% !important; }
  .lp-form button { width: 100%; }
  .lp-problem { grid-template-columns: 1fr !important; padding: 26px 20px !important; }
  .lp-hero { padding-top: 104px !important; gap: 40px !important; }
  .lp-hero-visual { min-height: 430px !important; }

  /* The hero glow sits at inset: -40px -60px, a deliberate bleed past the
     visual. While the visual was accidentally too narrow that bleed stayed on
     screen; once it filled its track the glow reached 40px past the viewport
     and the page scrolled sideways again. Clip the horizontal bleed only --
     the gradient is already near-transparent where it would be cut, so nothing
     visible is lost, and the vertical bleed is untouched. */
  .lp-hero-visual > div:first-child { left: 0 !important; right: 0 !important; }
  .lp-studio { gap: 32px !important; }
}
@media (max-width: 560px) {
  .lp-nav { gap: 10px !important; padding: 0 14px !important; }
  .lp-nav-alpha, .lp-nav-login { display: none !important; }
  .lp-nav-cta { padding: 7px 12px !important; }
  .lp-hero { padding-top: 96px !important; }
  .lp-hero-visual { min-height: 380px !important; }
  .lp-cal { width: 94% !important; padding: 14px 14px !important; }
  /* 68% + 46% is 114%, so these two cards overlap by design. On a wide visual
     the overlap lands on the postcard's empty right edge; at 335px it landed on
     its text, cutting the post title and the character counter mid-word. There
     is no vertical escape -- the phone occupies 138-374px of a 380px box -- so
     the layers separate horizontally instead: 62% + 40% still overlap, but only
     the card backgrounds touch and every line of text stays readable. */
  .lp-postcard { width: 62% !important; left: 0 !important; bottom: 26px !important; }
  .lp-phone { width: 40% !important; right: 0 !important; top: 138px !important; }

  /* Seven tracks across 375px leave roughly 36px per day, so the status label
     cannot be read no matter how it is clipped. Drop the text and keep the
     tinted pill with its glyph: the strip still says "these days are spoken
     for, this one is being edited", which is the entire point of the mock. */
  .lp-week { gap: 4px !important; }
  .lp-week > * { padding: 4px !important; min-height: 62px !important; }
  .lp-week > * > span { font-size: 0 !important; padding: 4px 0 !important; justify-content: center; }
}

/* The bar needs 361px: wordmark 113 + language switch 78 + CTA 119 plus gaps
   and padding. So it fits at 375 and breaks below -- hence 360, not something
   rounder. The wordmark is the cheapest 81px to reclaim and the mark alone
   still reads as the logo, but it is also the link's only accessible name, so
   it is hidden from layout rather than from the page: display: none would
   leave a link that a screen reader announces as nothing at all. */
@media (max-width: 360px) {
  .lp-nav-word {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0; border: 0;
    overflow: hidden; clip-path: inset(50%);
    white-space: nowrap;
  }
}

/* ---- Reduced motion ----------------------------------------------------
   Removes motion, keeps state. Reveal elements must be forced visible here:
   the script skips its reveal pass under this setting, but a stale
   data-hidden attribute would otherwise leave content invisible.           */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }
  [data-reveal], [data-reveal][data-hidden] { opacity: 1 !important; transform: none !important; }
}
