/* anti-slop: the values every build starts from.
   These are not suggestions. They are the numbers that stop the usual failures: cramped headings, one
   rounding on everything, text lines too long to read, sections that touch, cards in a row at different
   heights. Copy this file into the build, set the four brand values at the top, and use the tokens
   everywhere. Never hard-code a spacing number. A layout that needs a value not in this file is a layout
   that needs rethinking. */

:root {
  /* ---- the four things that change per brand ---------------------------------------------------- */
  --ink: #13262B;            /* body text: the dark teal of the Lawnster logo, near black */
  --paper: #FFFFFF;          /* the reading surface: white or a warm off-white, never dark */
  --accent: #17596A;         /* the teal banner of the Lawnster logo
                                (Lawn Care of Meridian), sampled by eye from their Google profile picture */
  --sans: "Switzer", system-ui, sans-serif;   /* self-hosted, from Fontshare */

  /* ---- spacing: one scale, every gap comes from it ------------------------------------------------ */
  --s-1: 4px;  --s-2: 8px;   --s-3: 12px;  --s-4: 16px;  --s-5: 24px;
  --s-6: 32px; --s-7: 48px;  --s-8: 64px;  --s-9: 96px;  --s-10: 128px;

  /* space INSIDE a thing is always smaller than space BETWEEN things: that is what makes it read */
  --gap-in-card: var(--s-5);           /* card padding */
  --gap-after-heading: 0.5em;          /* every heading gets air under it, never margin: 0 */
  --gap-after-body: var(--s-5);        /* before a button */
  --gap-between-blocks: var(--s-6);
  --gap-between-sections: clamp(64px, 8vw, 128px);   /* always bigger than anything inside a section */

  /* ---- type: a real scale, big enough to read on a phone ------------------------------------------ */
  --text-small: 15px;
  --text-body: clamp(17px, 1.1vw, 19px);
  --text-lead: clamp(19px, 1.4vw, 22px);
  --text-h3: clamp(21px, 1.6vw, 25px);
  --text-h2: clamp(28px, 3vw, 40px);
  --text-h1: clamp(36px, 5vw, 60px);
  --line-body: 1.55;
  --line-heading: 1.1;
  --measure: 68ch;            /* text never runs wider than this, whatever the container does */

  /* ---- rounding: a set, not one value ------------------------------------------------------------ */
  --r-photo: 4px;
  --r-card: 14px;
  --r-button: 8px;
  --r-pill: 999px;

  /* ---- everything else ---------------------------------------------------------------------------- */
  --line: rgba(20, 24, 29, .12);       /* hairlines */
  --shadow: 0 1px 2px rgba(20, 45, 90, .06), 0 12px 32px -16px rgba(20, 45, 90, .22);
  --tap: 44px;                          /* every tappable thing is at least this tall */

  /* ---- the layout grid: the same numbers as the red stripes in the Builder tab ---------------------
     Figma's Layout grid in CSS: Count, Gutter, Margin, plus a max width. Phone 4 columns, tablet 8,
     desktop 12. Change them here and the site and the stripes move together. */
  --grid-cols: 4;
  --grid-gutter: 16px;
  --grid-margin: var(--s-5);
  --grid-max: 1180px;
}
@media (min-width: 768px)  { :root { --grid-cols: 8; } }
@media (min-width: 1024px) { :root { --grid-cols: 12; } }

/* ---- the base the build inherits ------------------------------------------------------------------ */
body { margin: 0; background: var(--paper); color: var(--ink);
  font: 400 var(--text-body)/var(--line-body) var(--sans); }

h1, h2, h3 { line-height: var(--line-heading); margin: 0 0 var(--gap-after-heading); text-wrap: balance; }
h1 { font-size: var(--text-h1); max-width: 18ch; }   /* a headline past this is a sentence, not a heading */
h2 { font-size: var(--text-h2); max-width: 22ch; }
h3 { font-size: var(--text-h3); }
p  { margin: 0 0 var(--gap-after-body); max-width: var(--measure); }
small, .small { font-size: var(--text-small); }

section { padding-block: var(--gap-between-sections); }
.wrap { width: min(var(--grid-max), 100% - var(--grid-margin) * 2); margin-inline: auto; }

/* the columns: put .cols on a .wrap and place each child on the grid at desktop, for example
   @media (min-width: 1024px) { .about h2 { grid-column: 1 / span 6; } }
   A child with no placement takes the whole row, so phones stack by default. */
.cols { display: grid; grid-template-columns: repeat(var(--grid-cols), minmax(0, 1fr));
  column-gap: var(--grid-gutter); row-gap: var(--s-5); }
.cols > * { grid-column: 1 / -1; min-width: 0; }

/* buttons: a filled primary and an outline secondary, both real buttons, both tappable */
.btn { display: inline-flex; align-items: center; justify-content: center; min-height: var(--tap);
  padding: var(--s-3) var(--s-5); border-radius: var(--r-button); background: var(--accent); color: var(--paper);
  font-weight: 700; text-decoration: none; border: 2px solid var(--accent); }
.btn--ghost { background: transparent; color: var(--ink); border-color: var(--line); }
.btn + .btn { margin-left: var(--s-3); }
.btn-note { margin-top: var(--s-2); font-size: .85em; opacity: .75; }   /* the one true line under the button */

/* ---- grids: the columns follow the real count -------------------------------------------------------
   Two things: .grid--2. Four or eight: .grid--4. Five or six: .grid--2, three rows, or .stack.
   Three real things are NOT three equal cards in a row: use a list, or .stack so each gets a wide row.
   There is no three-column grid in this file on purpose. It is what every generated site does, and the
   gate fails on it. */
.grid { display: grid; gap: var(--s-5); grid-template-columns: 1fr; align-items: stretch; }
@media (min-width: 640px)  { .grid--2, .grid--4 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .grid--4 { grid-template-columns: repeat(4, 1fr); } }
.stack { display: grid; gap: var(--s-5); grid-template-columns: 1fr; }   /* wide rows, one per thing */

/* ---- everything in a row is the same height. Always. -----------------------------------------------
   The content never sets the height. The row stretches, the card is a column, the button is pushed to the
   bottom, and the title reserves two lines whether it needs them or not. Measure it in the browser: every
   item's height identical before it is shown. */
.grid > * { display: flex; flex-direction: column; min-height: 100%; }
.card { padding: var(--gap-in-card); border-radius: var(--r-card); border: 1px solid var(--line); }
.card > .btn, .card > .cta { margin-top: auto; align-self: flex-start; }
.card h3, .card .title { min-height: calc(2em * var(--line-heading)); display: -webkit-box;
  -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.card p { flex: 0 0 auto; }

/* pictures keep their own shape: the box is sized from the picture, never padded or cropped to fit.
   Pictures in one row share one aspect ratio, set once here per row, never a fixed height. */
img, video { display: block; max-width: 100%; height: auto; border-radius: var(--r-photo); }
.grid img, .grid video { width: 100%; aspect-ratio: var(--row-ratio, 4 / 3); object-fit: cover; }

/* the stacked, centered signup: field full width, button full width under it, never side by side */
.signup { max-width: 520px; margin-inline: auto; text-align: center; }
.signup input { width: 100%; min-height: var(--tap); padding: var(--s-3) var(--s-4);
  border: 2px solid var(--line); border-radius: var(--r-button); font: inherit; }
.signup .btn { width: 100%; margin-top: var(--s-3); }

/* ---- the browser's own parts, themed from the palette ---------------------------------------------
   The selection highlight, the focus ring, the caret, the form controls and the scrollbar all ship with
   browser defaults that belong to no design. Theming them is the cheapest sign a page was built, not
   assembled. The gate fails a stylesheet that leaves them alone. */
::selection { background: color-mix(in srgb, var(--accent) 24%, var(--paper)); color: var(--ink); }
:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; border-radius: var(--r-button); }
input, textarea, select { caret-color: var(--accent); accent-color: var(--accent); }
html { scrollbar-color: color-mix(in srgb, var(--ink) 30%, var(--paper)) var(--paper); }
.num, td, .price { font-variant-numeric: tabular-nums; }
a { color: var(--ink); text-decoration-thickness: 1px; text-underline-offset: .18em; }

/* motion can always be turned off. A visitor who asked for less motion gets the page still, in the same
   final state. Any build that animates anything keeps this block. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important; }
}

/* a picture spot that is waiting on a real photo. Marked, never faked. */
.waiting { display: grid; place-items: center; aspect-ratio: var(--row-ratio, 4 / 3);
  border: 2px dashed var(--line); border-radius: var(--r-photo); font-size: var(--text-small); }
