/* sample.css - chrome that marks this page as a demonstration.

   It may reference ONLY its own values. It declares no site token, so it can
   never leak into the design the DNA registry measures, and it is the last
   stylesheet loaded so it needs no !important.

   The flag must be readable at 375px at scroll 0 with JavaScript off, which is
   qa-definition-of-done.md §2 step 1a's own bar for "present". */

.sample-flag {
  background: #1E2E3D;
  color: #F9F8F6;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: 0.875rem;
  line-height: 1.45;
  padding: 0.75rem 1rem;
}

.sample-flag__inner {
  margin: 0 auto;
  max-width: 68rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  align-items: baseline;
  justify-content: space-between;
}

.sample-flag__text { margin: 0; max-width: 60ch; }
.sample-flag__text strong { color: #FFFFFF; }

.sample-flag__btn {
  background: #C84B31;
  color: #FFFFFF;
  text-decoration: none;
  font-weight: 700;
  white-space: nowrap;
  min-height: 44px;
  padding: 0 1.1rem;
  border-radius: 0.5rem;
  display: inline-flex;
  align-items: center;
}
.sample-flag__btn:hover { background: #A53C26; color: #FFFFFF; }
.sample-flag__btn:focus-visible { outline: 2px solid #FFFFFF; outline-offset: 2px; }

/* ---- The header, locked to the top ---------------------------------------
   Nic, 2026-09-20: the top navigation stays on screen while the page scrolls,
   on every sample. Before this, exactly one of the six did.

   WHY THE RULE IS HERE AND NOT IN THE SOURCE BUILDS. Four different states
   went into the duplication, and only one of them survived it:

     - tall-timber-tree-care's brief made the header sticky and the rule sits
       in site.css, which a sample copies. It worked. It was the only one.
     - redbrick-auto-care's brief ALSO made it sticky -- but the offset reads
       'var(--expiry-height)', and that token is DECLARED IN preview.css,
       which a sample strips. The var goes undefined, the declaration is
       invalid at computed-value time, inset-block-start falls back to 'auto',
       and a sticky box with an auto offset never sticks. Measured on the
       built page: position:sticky, inset-block-start:auto, header scrolling
       away with the content.
     - riverstone-landscape's brief made it sticky in preview.css itself, so
       the whole rule left with the file.
     - northfield-electric, rainhouse-gutter-co and cedar-and-stone were never
       sticky; their briefs did not ask for it, and they ship 'relative'.

   So two of the six are a DUPLICATION ARTEFACT and three are a DESIGN
   DIFFERENCE. Restating the rule here settles all five the same way without
   touching sites/: a real business's live preview is not ours to redesign on
   the strength of a marketing-page request, and the two artefact cases must
   not be "repaired" by editing a build that is already correct as built --
   with preview.css loaded, both of them stick exactly as their briefs say.

   inset-block-start is 0, never var(--expiry-height): a sample has no expiry
   bar. The flag above the header stays static flow on purpose -- it is a
   disclosure, read once, and pinning it would spend a permanent strip of
   every first screen (preview.css argues the same for the bar it replaces).
   And it is 'sticky', never 'fixed': sticky keeps the header's flow height
   from first paint, so nothing below it jumps and the change costs no CLS.

   z-index and an opaque background are NOT restated here. All six builds
   already set 'z-index: var(--z-header)' and 'background-color:
   var(--color-bg)' on this element, and this file reads no site token. */

.site-header {
  position: sticky;
  inset-block-start: 0;
}

/* Anchor targets have to clear the locked header.

   Every sample's nav is in-page links, and a fragment jump parks the target
   at the very top of the viewport -- under a header that is now pinned there.

   THE OFFSET IS MEASURED AT RUNTIME, NOT HARD-CODED, because the six headers
   do not agree on a height and no single number serves them. Measured on the
   served pages: 61px (cedar-and-stone at 375px) to 137px (riverstone at
   375px, whose brand -- 'Riverstone Landscape and Supply' -- is 265px wide
   and wraps the menu button onto a second row). A constant tall enough for
   the 137px header would drop a 79px hole above every heading on the 61px
   one; a constant sized for the 61px header hides headings on the other.
   So sample.js writes --sample-header-h from the header's own box, on load,
   after webfonts settle and on resize.

   The 5.5rem fallback is what a visitor with JavaScript off gets. It is not
   exact for them -- the noscript override in @shared:head-boilerplate opens
   the nav list, so their header is TALLER, not shorter -- but a fragment jump
   is one of several things that degrade with no JS here, and an offset that
   is close beats an offset of zero.

   scroll-padding on the scroll container, not scroll-margin on 'section[id]':
   one rule covers every fragment target whatever element it lands on, and it
   needs no per-build selector. 'node scripts/webdesign-samples.mjs
   sticky-check' clicks every nav link on the served pages and fails if a
   heading lands under the bar.

   THIS WAS ALREADY BROKEN ON THE ONE SAMPLE THAT WAS STICKY. Measured before
   any change here, all six of tall-timber-tree-care's nav links landed their
   section heading under the bar -- heading at 64px against a header bottom of
   77px (375px) and 81px (1280px). Its source build carries the same defect,
   because the brief's sticky rule went into site.css without the
   'scroll-margin-block-start' companion that preview.css's own comment
   prescribes. That build is NOT changed here; it is a live preview for a real
   business and a separate call. See DECISION.md "Sticky headers". */

html {
  scroll-padding-block-start: var(--sample-header-h, 5.5rem);
}

/* The reviews slot. Deliberately quiet: it is a statement, not a testimonial. */
.sample-note {
  border: 1px dashed currentColor;
  border-radius: 0.5rem;
  padding: 1.25rem 1.5rem;
  margin: 1.5rem 0 1rem;
  opacity: 0.85;
  max-width: 46rem;
}
.sample-note__lead { margin: 0 0 0.5rem; font-weight: 700; }
.sample-note__body { margin: 0; }

/* ---- The Sylentt conversion band -----------------------------------------
   Deliberately OUR colours, not the sample's: a visitor must never mistake
   this for the demo business's own contact form, which sits above it and is
   inert. Sylentt ink and accent, system font, no sample token touched. */

.sample-cta {
  background: #1E2E3D;
  color: #F9F8F6;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  padding: 3rem 1rem;
  line-height: 1.5;
}
.sample-cta__inner { max-width: 44rem; margin: 0 auto; }
.sample-cta__head { margin-bottom: 2rem; }
.sample-cta__eyebrow {
  margin: 0 0 0.5rem; font-size: 0.75rem; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase; color: #E9856F;
}
.sample-cta__title {
  margin: 0 0 0.75rem; font-size: 1.75rem; line-height: 1.2; color: #FFFFFF;
  font-family: inherit; font-weight: 700; letter-spacing: -0.01em;
}
.sample-cta__lead { margin: 0; color: rgba(249, 248, 246, 0.82); }

.sample-cta__form {
  background: rgba(249, 248, 246, 0.06);
  border: 1px solid rgba(249, 248, 246, 0.14);
  border-radius: 0.75rem;
  padding: 1.5rem;
}
.sample-cta__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.sample-cta__field { margin: 0; display: flex; flex-direction: column; }
.sample-cta__field--wide { grid-column: 1 / -1; }
.sample-cta__field label {
  font-size: 0.85rem; font-weight: 600; margin-bottom: 0.4rem;
  color: rgba(249, 248, 246, 0.92);
}
.sample-cta__field label span { color: #E9856F; }
.sample-cta__field input,
.sample-cta__field select {
  font: inherit; font-size: 1rem; min-height: 48px;
  padding: 0 0.85rem; border-radius: 0.5rem;
  border: 1px solid rgba(249, 248, 246, 0.24);
  background: #F9F8F6; color: #1E2E3D; width: 100%;
}
.sample-cta__field input:focus-visible,
.sample-cta__field select:focus-visible { outline: 2px solid #E9856F; outline-offset: 1px; }

.sample-cta__trap { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }

.sample-cta__more { margin-top: 1rem; border-top: 1px solid rgba(249, 248, 246, 0.14); padding-top: 0.75rem; }
.sample-cta__more summary {
  cursor: pointer; min-height: 44px; display: flex; align-items: center; gap: 0.5rem;
  font-weight: 600; color: rgba(249, 248, 246, 0.92);
  list-style: none;
}
.sample-cta__more summary::-webkit-details-marker { display: none; }
.sample-cta__more summary::before {
  content: "\203A";
  display: inline-block;
  font-size: 1.2em;
  line-height: 1;
  transition: transform 0.15s ease;
}
.sample-cta__more[open] summary::before { transform: rotate(90deg); }
.sample-cta__more summary:focus-visible { outline: 2px solid #E9856F; outline-offset: 2px; }
.sample-cta__more .sample-cta__grid { margin-top: 0.75rem; }

.sample-cta__actions { margin-top: 1.5rem; display: flex; flex-direction: column; gap: 0.75rem; align-items: flex-start; }
.sample-cta__submit {
  font: inherit; font-size: 1.05rem; font-weight: 700; cursor: pointer;
  background: #C84B31; color: #FFFFFF; border: 0;
  border-radius: 0.6rem; min-height: 52px; padding: 0 1.75rem;
}
.sample-cta__submit:hover { background: #A53C26; }
.sample-cta__submit:focus-visible { outline: 2px solid #FFFFFF; outline-offset: 2px; }
.sample-cta__fine { margin: 0; font-size: 0.8rem; color: rgba(249, 248, 246, 0.66); }

.sample-cta__foot { margin: 1.5rem 0 0; font-size: 0.85rem; color: rgba(249, 248, 246, 0.7); }
.sample-cta__foot strong { color: #F9F8F6; }
.sample-cta__foot a { color: #F9F8F6; text-decoration: underline; text-underline-offset: 0.2em; }

@media (max-width: 34rem) {
  .sample-cta__grid { grid-template-columns: 1fr; }
  .sample-cta__submit { width: 100%; }
}

/* ---- Back to top ---------------------------------------------------------
   Vanilla port of components/ui/BackToTop.tsx. Ships with the hidden
   attribute set, so with JavaScript off it never appears rather than sitting
   there doing nothing. */

.sample-totop {
  position: fixed; bottom: 1.5rem; right: 1.5rem; z-index: 9990;
  width: 3.5rem; height: 3.5rem; padding: 0; border: 0; cursor: pointer;
  background: transparent; color: #C84B31;
  display: flex; align-items: center; justify-content: center;
  animation: sample-totop-in 0.25s ease-out both;
}
.sample-totop[hidden] { display: none; }
.sample-totop:hover { transform: scale(1.1); }
.sample-totop:active { transform: scale(0.95); }
.sample-totop:focus-visible { outline: 2px solid #C84B31; outline-offset: 4px; border-radius: 0.5rem; }

.sample-totop__stack { display: flex; flex-direction: column; align-items: center; }
.sample-totop__stack svg { width: 2.6rem; height: 2.6rem; display: block; margin-bottom: -1.55rem; }
.sample-totop__stack svg:nth-child(1) { opacity: 1;   animation: sample-totop-nudge 7s ease-in-out infinite; }
.sample-totop__stack svg:nth-child(2) { opacity: 0.6; animation: sample-totop-nudge 7s ease-in-out 0.2s infinite; }
.sample-totop__stack svg:nth-child(3) { opacity: 0.3; animation: sample-totop-nudge 7s ease-in-out 0.4s infinite; margin-bottom: 0; }

@keyframes sample-totop-in { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: none; } }
@keyframes sample-totop-nudge { 0%, 4% { transform: translateY(0); } 5% { transform: translateY(-8px); } 7%, 100% { transform: translateY(0); } }

@media (prefers-reduced-motion: reduce) {
  .sample-flag, .sample-note { transition: none; }
  .sample-totop, .sample-totop__stack svg { animation: none; }
  .sample-totop:hover, .sample-totop:active { transform: none; }
}
