/* ===========================================================================
   Procure — the public page.

   Written by hand for this repository. The look follows LedgerMan (restrained
   neutrals, hairline borders, one accent used only for the primary action,
   generous vertical rhythm) but no line of CSS or markup is shared with it:
   LedgerMan's web app is Tailwind in a Next.js build, this is one stylesheet
   with no build step, and the two products share no code by design.

   ---------------------------------------------------------------------------
   COLOUR
   ---------------------------------------------------------------------------
   Every value below is taken from the Android app's own palette, so the site
   and the app cannot drift apart:
     android/app/src/main/java/in/ledgerman/procure/ui/theme/Palette.kt
     android/app/src/main/java/in/ledgerman/procure/ui/theme/Colours.kt

   The accent is two tokens, for the reason Colours.kt gives: the teal that is
   dark enough to carry white text as a *fill* is too dark to read as *ink* on
   a near-black surface, so the fill stays deep in dark mode and the ink goes
   pale. Using the fill as text in dark mode would be 3.4:1.

   ---------------------------------------------------------------------------
   CONTRAST, computed (WCAG 2.1 relative luminance). Every text pairing used
   on these pages, both schemes. Minimum required for body text: 4.5:1.

     LIGHT
       text      #0F1215  on surface  #FFFFFF  ... 18.79:1
       text      #0F1215  on raised   #F7F8F9  ... 17.67:1
       text      #0F1215  on sunken   #EEF0F2  ... 16.45:1
       muted     #535B64  on surface  #FFFFFF  ...  6.89:1
       muted     #535B64  on raised   #F7F8F9  ...  6.48:1
       muted     #535B64  on sunken   #EEF0F2  ...  6.03:1
       accentInk #0B6B63  on surface  #FFFFFF  ...  6.37:1
       accentInk #0B6B63  on raised   #F7F8F9  ...  5.99:1
       onAccent  #FFFFFF  on accent   #0B6B63  ...  6.37:1

     DARK
       text      #EEF0F2  on surface  #0F1215  ... 16.45:1
       text      #EEF0F2  on raised   #171B1F  ... 15.15:1
       text      #EEF0F2  on sunken   #0A0C0E  ... 17.15:1
       muted     #A3ABB4  on surface  #0F1215  ...  8.09:1
       muted     #A3ABB4  on raised   #171B1F  ...  7.45:1
       muted     #A3ABB4  on sunken   #0A0C0E  ...  8.44:1
       accentInk #5FCBBF  on surface  #0F1215  ...  9.65:1
       accentInk #5FCBBF  on raised   #171B1F  ...  8.89:1
       onAccent  #FFFFFF  on accent   #0F766E  ...  5.47:1

   Lowest text ratio anywhere on these pages: 5.47:1, in dark mode, white on
   the primary button. Nothing on these pages uses the palette's textFaint
   token: at 4.54:1 on white it clears the bar only on the plain surface, and
   it would fail on a raised card, so it is left out entirely rather than used
   carefully.

   Borders carry no information and are held to the 3:1 non-text floor:
   borderStrong is 3.41:1 on white and 4.14:1 on the dark surface.
   =========================================================================== */

:root {
  color-scheme: light dark;

  /* Neutrals, light scheme. */
  --surface: #ffffff;
  --surface-raised: #f7f8f9;
  --surface-sunken: #eef0f2;
  --border: #e1e4e8;
  --border-strong: #848c95;
  --text: #0f1215;
  --text-muted: #535b64;

  /* The accent. --accent is a fill and carries --on-accent; --accent-ink is
     the same colour used as type, and is never used as a fill. */
  --accent: #0b6b63;
  --on-accent: #ffffff;
  --accent-ink: #0b6b63;
  --accent-soft: #ddf3f0;

  /* The spacing scale, from the app's Dimens.kt. Nothing invents a gap. */
  --s-xs: 4px;
  --s-sm: 8px;
  --s-md: 12px;
  --s-lg: 16px;
  --s-xl: 20px;
  --s-2xl: 28px;
  --s-3xl: 40px;

  /* Radii, from the same file: control / card / sheet. */
  --r-control: 8px;
  --r-card: 12px;
  --r-sheet: 20px;

  /* The gutter every band's content sits inside. */
  --gutter: var(--s-xl);
  --measure: 68rem;

  /* System faces only. Nothing is downloaded. */
  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, "Noto Sans", sans-serif;
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, "Cascadia Mono", Menlo,
    Consolas, monospace;
}

@media (prefers-color-scheme: dark) {
  :root {
    --surface: #0f1215;
    --surface-raised: #171b1f;
    --surface-sunken: #0a0c0e;
    --border: #272d33;
    --border-strong: #6f7780;
    --text: #eef0f2;
    --text-muted: #a3abb4;

    --accent: #0f766e;
    --on-accent: #ffffff;
    --accent-ink: #5fcbbf;
    --accent-soft: #12302d;
  }
}

/* --------------------------------------------------------------- resets */

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

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

body {
  margin: 0;
  background: var(--surface);
  color: var(--text);
  font-family: var(--font-sans);
  /* body: 16px / 23px, from the app's type scale. */
  font-size: 1rem;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}

img,
svg {
  display: block;
  max-width: 100%;
}

/* ------------------------------------------------------- focus, always */

/* The one style that is never overridden. Visible in both schemes: the ink
   accent against either surface is 6.37:1 light and 9.65:1 dark. */
:where(a, button, [tabindex]):focus-visible {
  outline: 2px solid var(--accent-ink);
  outline-offset: 2px;
  border-radius: 3px;
}

/* Belt and braces for browsers without :focus-visible. */
:where(a, button, [tabindex]):focus {
  outline: 2px solid var(--accent-ink);
  outline-offset: 2px;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 50;
  padding: var(--s-sm) var(--s-md);
  background: var(--surface);
  color: var(--accent-ink);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-control);
  font-size: 0.875rem;
  font-weight: 500;
  text-decoration: none;
}

.skip:focus {
  left: var(--s-md);
  top: var(--s-md);
}

/* ------------------------------------------------------------- the grid */

.wrap {
  max-width: var(--measure);
  margin: 0 auto;
  padding-inline: var(--gutter);
}

/* ------------------------------------------------------------- top bar */

.bar {
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}

.bar-row {
  display: flex;
  align-items: center;
  gap: var(--s-lg);
  min-height: 60px;
  padding-block: var(--s-sm);
}

.mark {
  display: flex;
  align-items: baseline;
  gap: var(--s-sm);
  min-width: 0;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.mark-glyph {
  width: 22px;
  height: 22px;
  flex: none;
  align-self: center;
  color: var(--accent-ink);
}

.mark-text {
  font-size: 1.1875rem;
}

/* One line or nothing. At 360px this wrapped onto a second line beside the
   bar's button and the header looked like an accident; held to one line it
   was clipped by the button instead, so below 26rem it simply goes. Nothing
   is lost: the footer of every page says the same thing in full. */
.mark-by {
  font-size: 0.75rem;
  font-weight: 400;
  white-space: nowrap;
  color: var(--text-muted);
}

@media (max-width: 26rem) {
  .mark-by {
    display: none;
  }
}

.bar-nav {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--s-xs);
  font-size: 0.875rem;
}

.bar-nav a:not(.btn) {
  display: none;
  padding: var(--s-sm) var(--s-md);
  border-radius: var(--r-control);
  color: var(--text-muted);
  text-decoration: none;
}

.bar-nav a:not(.btn):hover {
  color: var(--text);
  background: var(--surface-raised);
}

@media (min-width: 40rem) {
  .bar-nav a:not(.btn) {
    display: block;
  }
}

/* -------------------------------------------------------------- buttons */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* The app's 48dp touch floor. This is used one-handed in a crowded hall. */
  min-height: 48px;
  padding: var(--s-md) var(--s-2xl);
  border-radius: var(--r-control);
  border: 1px solid transparent;
  font: inherit;
  font-size: 0.9375rem;
  font-weight: 500;
  text-align: center;
  text-decoration: none;
}

/* Only the bar's button is held to one line. The buttons in the body are
   allowed to wrap: at 360px the iPhone slot's label is close to the full
   width, and wrapped text inside the button is better than text outside it. */
.bar-nav .btn {
  white-space: nowrap;
}

.btn-sm {
  min-height: 36px;
  padding: var(--s-sm) var(--s-lg);
  font-size: 0.875rem;
}

.btn-primary {
  background: var(--accent);
  color: var(--on-accent);
}

.btn-primary:hover {
  /* A touch deeper on hover, held above the white it carries. */
  filter: brightness(0.92);
}

.btn-quiet {
  border-color: var(--border-strong);
  color: var(--text);
  background: var(--surface);
}

.btn-quiet:hover {
  background: var(--surface-raised);
}

/* The iPhone slot. Not a link and not a button — there is nothing to point
   at yet — so it is styled as a plain statement of fact: dashed, quiet, and
   obviously not pressable. It is not focusable. */
.btn-pending {
  border-style: dashed;
  border-color: var(--border-strong);
  color: var(--text-muted);
  background: transparent;
  cursor: default;
}

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

h1,
h2,
h3 {
  margin: 0;
  letter-spacing: -0.015em;
  text-wrap: balance;
}

h1 {
  /* display, 32px, up to 44px where there is room. */
  font-size: clamp(2rem, 1.4rem + 2.6vw, 2.75rem);
  line-height: 1.12;
  font-weight: 700;
  margin-top: var(--s-lg);
  max-width: 34ch;
}

h2 {
  /* title, 24px, up to 30px. */
  font-size: clamp(1.5rem, 1.3rem + 0.9vw, 1.875rem);
  line-height: 1.22;
  font-weight: 600;
  margin-top: var(--s-md);
  max-width: 34ch;
}

h3 {
  /* heading, 19px. */
  font-size: 1.1875rem;
  line-height: 1.3;
  font-weight: 600;
}

p {
  margin: 0;
}

.eyebrow {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  line-height: 1.4;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--accent-ink);
}

.lede {
  margin-top: var(--s-xl);
  font-size: 1.0625rem;
  line-height: 1.6;
  color: var(--text-muted);
  max-width: 56ch;
}

.prose {
  margin-top: var(--s-lg);
  color: var(--text-muted);
  line-height: 1.6;
  max-width: 62ch;
}

.note {
  padding-left: var(--s-md);
  border-left: 2px solid var(--border-strong);
}

.fineprint {
  margin-top: var(--s-xl);
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--text-muted);
  max-width: 54ch;
}

.nowrap {
  white-space: nowrap;
}

/* --------------------------------------------------------------- bands */

.hero {
  padding-block: var(--s-3xl) calc(var(--s-3xl) + var(--s-xl));
  border-bottom: 1px solid var(--border);
}

.band {
  padding-block: calc(var(--s-3xl) + var(--s-sm));
  border-bottom: 1px solid var(--border);
}

.band-raised {
  background: var(--surface-raised);
}

@media (min-width: 48rem) {
  .hero {
    padding-block: calc(var(--s-3xl) * 1.6) calc(var(--s-3xl) * 1.8);
  }
  .band {
    padding-block: calc(var(--s-3xl) * 1.5);
  }
}

.cta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-md);
  margin-top: var(--s-2xl);
}

.cta-tight {
  margin-top: var(--s-xl);
}

/* At 360px a button pair reads better stacked and full width than wrapped. */
@media (max-width: 26rem) {
  .cta .btn {
    width: 100%;
  }
}

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

.cards {
  list-style: none;
  margin: var(--s-2xl) 0 0;
  padding: 0;
  display: grid;
  gap: var(--s-md);
  grid-template-columns: 1fr;
}

@media (min-width: 30rem) {
  .cards {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 52rem) {
  .cards {
    grid-template-columns: repeat(3, 1fr);
  }
}

.card {
  padding: var(--s-lg);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  background: var(--surface);
}

.card h3 {
  font-size: 1rem;
}

.card p {
  margin-top: var(--s-sm);
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--text-muted);
}

.card-lead {
  padding: var(--s-xl);
}

.card-lead h3 {
  font-size: 1.1875rem;
}

.split {
  display: grid;
  gap: var(--s-xl);
  margin-top: var(--s-2xl);
  grid-template-columns: 1fr;
}

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

.split .prose {
  margin-top: var(--s-md);
}

/* ----------------------------------------------------- screenshot slots */

.shots {
  display: grid;
  gap: var(--s-2xl);
  margin-top: var(--s-2xl);
  grid-template-columns: 1fr;
  justify-items: center;
}

@media (min-width: 46rem) {
  .shots {
    grid-template-columns: repeat(3, 1fr);
    gap: var(--s-xl);
  }
}

/* Narrow enough that three stacked frames are a scroll rather than a journey;
   a 9:19.5 frame is nearly three times as tall as it is wide. */
.shot-fig {
  margin: 0;
  width: 100%;
  max-width: 216px;
}

@media (min-width: 46rem) {
  .shot-fig {
    max-width: 260px;
  }
}

/* The bezel. */
.shot {
  padding: var(--s-sm);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sheet);
  background: var(--surface);
}

/* The screen. This element IS the image: the screenshot arrives as the first
   background layer and the hairline pattern beneath it is what the slot looks
   like until then — a frame waiting for a capture rather than a broken image.
   Nothing is nested inside it, because a child would paint over the real
   screenshot once the file exists. */
.shot-screen {
  aspect-ratio: 9 / 19.5;
  border-radius: var(--r-control);
  background-color: var(--surface-sunken);
  background-image:
    var(--shot, none),
    repeating-linear-gradient(
      135deg,
      transparent 0 10px,
      var(--border) 10px 11px
    );
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  box-shadow: inset 0 0 0 1px var(--border);
}

.slot-1 {
  --shot: url("img/screen-1.png");
}

.slot-2 {
  --shot: url("img/screen-2.png");
}

.slot-3 {
  --shot: url("img/screen-3.png");
}

figcaption {
  margin-top: var(--s-md);
  font-size: 0.875rem;
  line-height: 1.45;
  color: var(--text-muted);
  text-align: center;
}

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

.foot {
  padding-block: var(--s-2xl);
  background: var(--surface-raised);
}

.foot-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-md) var(--s-xl);
}

.foot-note {
  font-size: 0.875rem;
  color: var(--text-muted);
}

.foot-nav {
  margin-left: auto;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-md) var(--s-xl);
  font-size: 0.875rem;
}

.foot-nav a {
  color: var(--accent-ink);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}

.foot-nav a:hover {
  border-bottom-color: currentColor;
}

/* ------------------------------------------------ privacy / terms pages */

.doc {
  padding-block: var(--s-2xl) calc(var(--s-3xl) + var(--s-xl));
}

.doc .wrap {
  max-width: 46rem;
}

.doc h1 {
  max-width: 28ch;
}

.doc h2 {
  margin-top: var(--s-3xl);
  font-size: 1.3125rem;
  max-width: 40ch;
}

.doc p,
.doc li {
  margin-top: var(--s-md);
  line-height: 1.65;
  color: var(--text-muted);
  max-width: 68ch;
}

.doc ul {
  margin: var(--s-md) 0 0;
  padding-left: var(--s-xl);
}

.doc li {
  margin-top: var(--s-sm);
}

.doc a {
  color: var(--accent-ink);
}

.doc .stamp {
  margin-top: var(--s-lg);
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  color: var(--text-muted);
}

.back {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: 0.875rem;
  color: var(--accent-ink);
  text-decoration: none;
}

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

/* A short summary at the top of the policy. Accent wash, accent ink: 5.51:1
   in light, 7.25:1 in dark. */
.summary {
  margin-top: var(--s-xl);
  padding: var(--s-lg) var(--s-xl);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  background: var(--accent-soft);
}

.summary p,
.summary li {
  color: var(--text);
}

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