/* co-cal.com's only stylesheet (decision 0014, #115). The colours are the app's design tokens, named as in
   src/ui/theme/tokens.ts (surfaceRaised is --surface-raised); src/privacy/site.test.ts fails if one drifts.
   The phone's own system fonts: nothing is loaded from any other host. Mobile first: 390 px, then wider. */

:root {
  color-scheme: light dark;
  --surface: #FBF9FE;
  --surface-raised: #FFFFFF;
  --surface-sunken: #F1EDF7;
  --ink: #1F1630;
  --ink-muted: #5E5470;
  --line: #DAD3E6;
  --line-strong: #857A99;
  --purple: #5B2E91;
  --on-purple: #FFFFFF;
  --purple-soft: #EDE4F8;
  --purple-ink: #3E1C69;
  --co-red: #E5484D;
  --co-blue: #3B82F6;
  --yes: #0F6E53;
  --no: #A8231B;
}

@media (prefers-color-scheme: dark) {
  :root {
    --surface: #151020;
    --surface-raised: #1F1830;
    --surface-sunken: #0E0A17;
    --ink: #F3EEFB;
    --ink-muted: #B6ACC8;
    --line: #342A47;
    --line-strong: #8A7FA2;
    --purple: #B79DF2;
    --on-purple: #1C0F33;
    --purple-soft: #2D2048;
    --purple-ink: #DCCBFB;
    --co-red: #F07A6E;
    --co-blue: #80A7F4;
    --yes: #63CFA6;
    --no: #F4917F;
  }
}

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

[hidden] {
  display: none !important;
}

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

body {
  margin: 0;
  background: var(--surface);
  color: var(--ink);
  font: 1rem/1.5 system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  overflow-wrap: anywhere;
}

header.site,
main,
footer.site {
  max-width: 44rem;
  margin: 0 auto;
  padding: 0 1.5rem;
}

header.site {
  padding-top: 1rem;
  padding-bottom: 1rem;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 2.75rem;
  color: var(--ink);
  font-weight: 600;
  text-decoration: none;
}

.brand img {
  display: block;
}

main {
  padding-bottom: 2rem;
}

footer.site {
  border-top: 1px solid var(--line);
  padding-top: 1rem;
  padding-bottom: 2rem;
  color: var(--ink-muted);
  font-size: 0.875rem;
}

h1 {
  font-size: 1.875rem;
  line-height: 1.2;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 1.5rem 0 1rem;
}

h2 {
  font-size: 1.375rem;
  line-height: 1.3;
  font-weight: 600;
  margin: 2rem 0 0.75rem;
}

h3 {
  font-size: 1.0625rem;
  line-height: 1.3;
  font-weight: 600;
  margin: 1.5rem 0 0.5rem;
}

p,
ul {
  margin: 0 0 1rem;
}

ul {
  padding-left: 1.25rem;
}

li + li {
  margin-top: 0.5rem;
}

a {
  color: var(--purple);
  text-underline-offset: 0.15em;
}

a:focus-visible {
  outline: 3px solid var(--purple);
  outline-offset: 2px;
  border-radius: 4px;
}

code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.9em;
}

.lead {
  font-size: 1.125rem;
  color: var(--ink-muted);
}

.muted {
  color: var(--ink-muted);
}

/* The one call to action: at least 44 pt tall, as in the app. */
.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 3rem;
  padding: 0 1.5rem;
  border-radius: 14px;
  background: var(--purple);
  color: var(--on-purple);
  font-weight: 600;
  text-decoration: none;
}

.button:focus-visible {
  outline-color: var(--ink);
}

.notice {
  background: var(--purple-soft);
  color: var(--purple-ink);
  border-radius: 14px;
  padding: 1rem;
}

.notice p:last-child {
  margin-bottom: 0;
}

/* The privacy policy's one table. On a phone each row becomes a card, with every cell under its heading,
   so nothing scrolls sideways. */
table {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 1rem;
}

th,
td {
  text-align: left;
  vertical-align: top;
  padding: 0.75rem 0.5rem;
  border-bottom: 1px solid var(--line);
  /* anywhere (on body) would let a column shrink to one letter wide; this breaks only a word that can't fit. */
  overflow-wrap: break-word;
}

th {
  font-weight: 600;
}

@media (max-width: 599px) {
  thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }

  tr {
    display: block;
    background: var(--surface-raised);
    border: 1px solid var(--line);
    border-radius: 14px;
    padding: 0.5rem 1rem;
    margin-bottom: 0.75rem;
  }

  td {
    display: block;
    padding: 0.5rem 0;
    border-bottom: 0;
  }

  td::before {
    content: attr(data-label);
    display: block;
    font-weight: 600;
    color: var(--ink-muted);
    font-size: 0.875rem;
  }
}

/* The home page (#222). Wider than the reading pages: the headline and the calendar pad side by side on a
   desktop, one above the other on a phone. */
.home header.site,
.home main,
.home footer.site {
  max-width: 72rem;
}

.hero-pin {
  display: grid;
  grid-template-rows: auto;
  gap: 1rem;
  padding-bottom: 1.5rem;
}

.hero h1 {
  font-size: 2rem;
  margin-top: 0.5rem;
}

.stores {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  list-style: none;
  padding: 0;
}

/* The app stores, until the listings exist: plainly not links, and saying so. */
.store {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  min-height: 3rem;
  margin: 0;
  padding: 0.375rem 1rem;
  border: 1.5px solid var(--line-strong);
  border-radius: 14px;
  background: var(--surface-raised);
  line-height: 1.2;
}

li.store + li.store {
  margin-top: 0;
}

.store-soon {
  color: var(--ink-muted);
  font-size: 0.8125rem;
}

.store-name {
  font-size: 1.0625rem;
  font-weight: 600;
}

.beta {
  color: var(--ink-muted);
  font-size: 0.9375rem;
}

/* The calendar pads and the feature tour (#222, #226). Without the 3D (reduced motion, no WebGL, scripts off,
   hero.js failing to load, or the 3D stopping for any reason): the still image, then the eight pages' captions as
   cards. With it (html.hero-3d, then html.hero-live once a frame is drawn): the canvas, one caption at a time,
   and the controls. The still stays until the first frame. */
.hero-pin {
  grid-template-areas: "copy" "stage" "tour";
}

.hero-copy {
  grid-area: copy;
}

.hero-show {
  display: contents;
}

.hero-stage {
  grid-area: stage;
  position: relative;
  width: 100%;
  max-width: 32.5rem;
  margin: 0;
  justify-self: center;
}

.hero-still {
  display: block;
  width: 100%;
  height: auto;
}

.hero-tour {
  grid-area: tour;
}

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

/* The features as cards. */
.hero-features {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 0.75rem;
  list-style: none;
  padding: 0;
  margin: 0;
}

.hero-features li {
  margin: 0;
  padding: 1rem 1.25rem;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--surface-raised);
}

.hero-features strong {
  display: block;
  font-weight: 600;
}

.hero-features span {
  display: block;
  color: var(--ink-muted);
}

/* The last card is the finale: the purple of the free day. */
.hero-features li:last-child {
  background: var(--purple-soft);
  border-color: transparent;
  color: var(--purple-ink);
}

.hero-features li:last-child span {
  color: var(--purple-ink);
}

/* When motion is welcome the hero keeps a full screen's height, so nothing below it jumps if the 3D starts. */
@media (prefers-reduced-motion: no-preference) {
  .hero-pin {
    min-height: 100vh;
    min-height: 100svh;
  }
}

/* The 3D tour. The pinned stretch is seven steps of 55% of a screen: one per page turn. Layouts, by the screen's
   shape (hero.js reads which applies):
   - wide and landscape, not short (desktops, laptops, tablets on their side): the copy beside the pads, and the
     whole hero pinned;
   - one column (phones, upright tablets, unfolded foldables): the copy scrolls by first, then the pads and the
     captions hold the whole screen while the pages turn;
   - short (under 480 px tall: a phone on its side, a flip phone's cover): nothing pinned; the buttons, dots, a
     tap on the pad or the arrow keys turn the pages.
   The canvas has a box of its own in every layout: nothing drawn in it can overlap any text. */
.hero-3d .hero {
  position: relative;
  height: 485vh;
  height: calc(100svh + 385svh);
}

.hero-3d .hero-pin {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  grid-template-rows: auto minmax(0, 1fr);
  grid-template-areas: "copy" "show";
  padding-top: 0.5rem;
}

.hero-3d .hero-show {
  grid-area: show;
  display: grid;
  grid-template-rows: minmax(12rem, 1fr) auto;
  grid-template-areas: "stage" "tour";
  gap: 0.5rem;
  min-height: 0;
  padding-bottom: 0.75rem;
}

.hero-3d .hero-stage {
  max-width: none;
  height: 100%;
  min-height: 0;
  cursor: pointer;
}

.hero-3d .hero-still {
  position: absolute;
  left: 50%;
  top: 50%;
  width: auto;
  height: auto;
  max-width: min(100%, 32.5rem);
  max-height: 100%;
  transform: translate(-50%, -50%);
}

/* One caption at a time: the current page's. The others stay in the list, out of sight, for screen readers. */
.hero-3d .hero-features {
  display: block;
  min-height: 4.5rem;
  text-align: center;
}

.hero-3d .hero-features li {
  padding: 0.25rem 0.5rem;
  border: 0;
  background: none;
  color: var(--ink);
}

.hero-3d .hero-features li:not(.is-current) {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.hero-3d .hero-features li:last-child {
  width: fit-content;
  max-width: 100%;
  margin: 0 auto;
  padding: 0.5rem 1rem;
  border-radius: 14px;
  background: var(--purple-soft);
}

.hero-live .hero-features li.is-current {
  animation: caption-in 250ms cubic-bezier(0.05, 0.7, 0.1, 1);
}

@keyframes caption-in {
  from {
    opacity: 0;
    transform: translateY(0.25rem);
  }
}

.hero-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0 0.25rem;
  margin-top: 0.25rem;
}

.hero-step {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.75rem;
  min-height: 2.75rem;
  padding: 0 0.75rem;
  border: 1.5px solid var(--line-strong);
  border-radius: 999px;
  background: var(--surface-raised);
  color: var(--ink);
  font: inherit;
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
}

.hero-step:disabled {
  opacity: 0.4;
  cursor: default;
}

.hero-dots {
  display: flex;
  justify-content: center;
}

.hero-dot {
  position: relative;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.hero-dot::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 999px;
  background: var(--line-strong);
  transform: translate(-50%, -50%);
  transition: width 250ms cubic-bezier(0.2, 0, 0, 1), background-color 250ms cubic-bezier(0.2, 0, 0, 1);
}

.hero-dot[aria-current]::before {
  width: 1.5rem;
  background: var(--purple);
}

.hero-step:focus-visible,
.hero-dot:focus-visible {
  outline: 3px solid var(--purple);
  outline-offset: -3px;
  border-radius: 999px;
}

/* On a narrow screen the dots take their own row above Previous and Next, out to the screen's edges (eight 44 px
   targets are 352 px); on the narrowest, two rows of four. */
@media (max-width: 30rem) {
  .hero-dots {
    order: -1;
    width: calc(100% + 3rem);
    margin: 0 -1.5rem;
  }

  .hero-controls {
    gap: 0 3rem;
  }
}

@media (max-width: 22.4375rem) {
  .hero-dots {
    display: grid;
    grid-template-columns: repeat(4, 2.75rem);
    justify-content: center;
  }
}

/* Scroll snapping, proximity only: an invisible marker at each page's place (hero.js), so a scroll that stops
   near a page settles on it. Only while the hero is pinned. */
html.hero-snapping {
  scroll-snap-type: y proximity;
}

.hero-snap {
  position: absolute;
  left: 0;
  width: 1px;
  height: 1px;
  pointer-events: none;
  scroll-snap-align: start;
}

/* One column: the copy scrolls by first, then the pads and captions hold the screen (the pinned stretch comes
   from the pin's padding). The canvas also runs to both edges of the screen, so a pad's soft shadow is never
   cut off by the page margin; there is no text beside it. */
@media not all and (min-width: 52.5rem) and (min-aspect-ratio: 6/5) and (min-height: 30.0625rem) {
  .hero-3d .hero {
    height: auto;
  }

  /* Block layout, not grid: a sticky box travels only within its containing block's content, and a grid item's
     containing block is its own grid area. The pinned stretch is an empty box after it (::after). */
  .hero-3d .hero-pin {
    display: block;
    position: static;
    height: auto;
    padding-bottom: 0;
  }

  .hero-3d .hero-pin::after {
    content: "";
    display: block;
    height: 385vh;
    height: 385svh;
  }

  .hero-3d .hero-copy {
    margin-bottom: 1rem;
  }

  .hero-3d .hero-show {
    position: sticky;
    top: 0;
    height: 100vh;
    height: 100svh;
  }

  .hero-3d .hero-stage {
    width: calc(100% + 3rem);
    margin: 0 -1.5rem;
  }
}

/* Short screens: nothing pinned (see above). The pads and captions take one screen and scroll like anything
   else. */
@media (max-height: 30rem) {
  .hero-3d .hero {
    height: auto;
  }

  .hero-3d .hero-pin {
    position: static;
    height: auto;
    min-height: 0;
    padding-bottom: 1.5rem;
  }

  .hero-3d .hero-show {
    position: relative;
    height: 100vh;
    height: 100svh;
  }

  .hero-3d .hero-pin::after {
    display: none;
  }

  .hero h1 {
    font-size: 1.75rem;
  }

  /* Room is short: the caption's second sentence stays for screen readers only. */
  .hero-3d .hero-features span {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .hero-3d .hero-show {
    grid-template-rows: minmax(9rem, 1fr) auto;
  }

  .hero-3d .hero-features {
    min-height: 2.5rem;
  }
}

.hero-canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  opacity: 0;
  pointer-events: none;
  /* duration.celebrate, easing.enter */
  transition: opacity 700ms cubic-bezier(0.05, 0.7, 0.1, 1);
}

.hero-live .hero-canvas {
  opacity: 1;
}

.hero-live .hero-still {
  opacity: 0;
  visibility: hidden;
  transition: opacity 700ms cubic-bezier(0.05, 0.7, 0.1, 1), visibility 0s linear 700ms;
}

.points {
  padding: 1rem 0 1rem;
}

.point-list {
  display: grid;
  gap: 0.75rem;
  list-style: none;
  padding: 0;
  margin: 0 0 1.5rem;
}

.point-list li {
  margin: 0;
  padding: 1rem 1.25rem;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--surface-raised);
}

.point-list h3 {
  margin-top: 0;
}

.point-list p {
  margin: 0;
  color: var(--ink-muted);
}

@media (min-width: 45rem) {
  .hero h1 {
    font-size: 2.75rem;
    line-height: 1.1;
    letter-spacing: -0.02em;
  }
}

/* Wide and landscape, and not short: the copy beside the pads. (A short screen, a phone on its side, stacks
   them.) Without the 3D, the feature cards run full width under both. */
@media (min-width: 52.5rem) and (min-aspect-ratio: 6/5) and (min-height: 30.0625rem) {
  .hero-pin {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
    grid-template-areas: "copy stage" "tour tour";
    align-items: center;
    column-gap: 2rem;
  }

  .hero-3d .hero-pin {
    grid-template-rows: minmax(0, 1fr);
    grid-template-areas: "copy show";
    padding-top: 0;
  }

  .hero-3d .hero-show {
    height: 100%;
    padding-top: 1rem;
  }

  .hero h1 {
    font-size: 3.25rem;
    line-height: 1.08;
  }

  .hero .lead {
    font-size: 1.25rem;
  }
}

@media (min-width: 52.5rem) {
  .point-list {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero-canvas,
  .hero-still,
  .hero-dot::before {
    transition: none;
  }

  .hero-live .hero-features li.is-current {
    animation: none;
  }
}
