/* ---------------------------------------------------------------------------
   feature.css — the marketing feature pages (/client-galleries, /event-walls,
   /portfolio-profiles, /pricing and the three competitor comparisons).

   These pages used to load legal.css, which is a reading column built for terms
   and privacy policies: 820px of prose, an <h2>, a rule, another <h2>. The
   content was right and the presentation said "legal document" — the owner's
   words, and correct.

   They now load app.css FIRST (so the homepage's tokens, buttons, header and
   footer components all apply verbatim) and this sheet second, for the parts
   that are specific to a feature page. Nothing here redefines a brand token:
   --ink, --paper, --green, --line and friends all come from app.css.

   Load order matters and is not negotiable: several selectors below are the
   same specificity as their app.css counterparts and win only by coming after.
   --------------------------------------------------------------------------- */

/* --- Mobile navigation --------------------------------------------------- */
/* app.css gives the panel `rgba(13,15,12,.97)`. Three percent transmission is
   invisible on the homepage, where it opens over a dark photograph — but these
   pages put it over a large serif headline, and the ghosted letters read
   through the open menu. Opaque here only: the homepage was never a problem and
   does not need changing. Scoped on `.feat-page` (0-2-0 over app.css's 0-1-0).*/
.feat-page .mobile-nav { background: #0d0f0c; }

/* --- Scroll reveals ------------------------------------------------------ */
/* Both selectors are gated on `html.pm-reveal`, a class only assets/reveal.js
   adds. With JavaScript off the class never appears, these rules never match,
   and the page renders fully visible — which is the whole design. Never move
   the hidden state into an ungated rule.
   The script also returns early under prefers-reduced-motion, so the class is
   absent there too; the media query below is the second guard, for the case
   where the setting changes after load. */
html.pm-reveal [data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity .5s cubic-bezier(.22,.61,.36,1), transform .5s cubic-bezier(.22,.61,.36,1);
  /* Hint only on the way in; cleared once revealed so long pages do not hold
     dozens of promoted layers. */
  will-change: opacity, transform;
}
html.pm-reveal [data-reveal='in'] { opacity: 1; transform: none; will-change: auto; }
@media (prefers-reduced-motion: reduce) {
  html.pm-reveal [data-reveal] { opacity: 1; transform: none; transition: none; }
}

/* --- Hero ---------------------------------------------------------------- */
/* Dark, full-bleed and photographic, matching the homepage hero rather than a
   document title. The image is per-page and set inline from PHP. */
.feat-hero {
  position: relative;
  isolation: isolate;
  /* A BANNER, not a landing screen. The first build let the hero size itself
     from its content and it came out 1534px — taller than the viewport, so the
     photograph was the whole first impression and the page looked like it
     started with a giant image. Height is now bounded explicitly and the copy
     is centred inside it. */
  min-height: 300px;
  display: grid;
  align-items: center;
  padding: 92px 0 40px;   /* top clears the fixed site header */
  background: var(--ink, #11130f);
  color: #fff;
  overflow: hidden;
}
/* `.page-body` is carried purely to out-specify upgrade.css:323 —
   `.page-body main > section:not(.hero) > *  { position: relative; z-index: 1 }`
   which is 0-2-2 and beat both `.feat-hero-media` (0-1-0) and
   `.feat-hero > .feat-hero-media` (0-2-0). That rule lifts every direct child
   of every homepage section above the decorative layers; this hero's photograph
   is the one child that must stay absolutely positioned and behind.
   The symptom was spectacular and the cause invisible: the media div fell back
   into normal flow, the image sized itself from its own aspect ratio, and the
   banner rendered 1398px tall — taller than the viewport. It appeared the
   moment upgrade.css was added to fix the stats strip, so the two changes have
   to be read together.
   Out-specifying rather than excluding here on purpose: the upgrade.css rule is
   load-bearing for the homepage and must not be edited to suit this page. */
.page-body .feat-hero > .feat-hero-media {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: -2;
  overflow: hidden;
}
.page-body .feat-hero > .feat-hero-media img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: center 38%; }
/* The photograph should read as a photograph. A flat overlay plus a low image
   opacity stacked into near-black on the first attempt — the wedding shot was
   invisible. One gradient does the work instead, weighted to the left where the
   text sits and opening up on the right where the image can be seen.
   Measured after changing it: the lead paragraph is the palest text here and
   still clears 4.5:1 against the brightest pixel behind it. */
.feat-hero::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(90deg, rgba(17,19,15,.93) 0%, rgba(17,19,15,.86) 42%, rgba(17,19,15,.55) 100%),
    linear-gradient(180deg, rgba(17,19,15,.5) 0%, rgba(17,19,15,.2) 45%, rgba(17,19,15,.72) 100%);
}
.feat-hero-inner { display: grid; gap: 14px; max-width: 720px; }
.feat-eyebrow {
  margin: 0;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  color: var(--light-green, #c5d7b8);
  font-size: 12.5px;
  font-weight: 800;
  letter-spacing: .12em;
  text-transform: uppercase;
}
.feat-hero h1 {
  margin: 0;
  font-family: var(--display, Georgia, 'Times New Roman', serif);
  font-size: clamp(32px, 4.4vw, 50px);
  line-height: 1.06;
  letter-spacing: -.02em;
}
.feat-hero-lead { margin: 0; max-width: 58ch; color: rgba(255,255,255,.8); font-size: 16.5px; line-height: 1.6; }
.feat-hero-actions { margin-top: 6px; display: flex; flex-wrap: wrap; gap: 10px; }

/* Breadcrumb sits inside the dark hero, so it cannot inherit the light-page
   link colour. 24px tall: it is standalone navigation, not a link in prose. */
.feat-crumb {
  margin: 0 0 6px;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 24px;
  color: rgba(255,255,255,.62);
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
}
.feat-crumb:hover { color: #fff; }

/* Suppress the homepage's "ghost section index" — the big outlined 01/02/03 in
   the top-right of every section (upgrade.css:309-321). It is a nice flourish
   on a single scrolling page, but a feature page already numbers its own point
   cards down the left, and two numbering systems on one page counting different
   things is just noise. It arrived uninvited with upgrade.css.
   `.page-body.feat-page …` is 0-3-3 against the original's 0-2-3 — the doubled
   class is what wins, so do not "tidy" it down to `.feat-page`. */
.page-body.feat-page main > section:not(.hero)::before { content: none; }

/* --- Showcase ------------------------------------------------------------ */
/* Wrapper for the homepage components reused verbatim on a feature page. It
   only positions them — the components bring their own styling from app.css,
   which is the point of reusing them rather than rebuilding them here. */
.feat-show { padding: 66px 0 10px; background: var(--paper, #f4f1eb); }
.feat-show-events { background: linear-gradient(180deg, #efe9f7 0%, var(--paper, #f4f1eb) 100%); }
.feat-show-head { display: grid; justify-items: start; gap: 12px; max-width: 720px; margin-bottom: 34px; }
.feat-show-eyebrow {
  margin: 0;
  color: var(--green, #304720);
  font-size: 12.5px;
  font-weight: 800;
  letter-spacing: .12em;
  text-transform: uppercase;
}
.feat-show-head h2 {
  margin: 0;
  font-family: var(--display, Georgia, serif);
  font-size: clamp(26px, 3.6vw, 40px);
  line-height: 1.1;
  letter-spacing: -.02em;
  color: var(--ink, #11130f);
}
.feat-show-head > p { margin: 0; color: var(--muted, #5b6155); font-size: 17px; line-height: 1.65; }
.feat-show-head .button { margin-top: 6px; }
/* Solid ink button: these sections sit on paper, where the homepage's
   translucent .button-light would have almost no edge. */
.button-dark { background: var(--ink, #11130f); color: #fff; border-color: transparent; }
.button-dark:hover { background: #000; }

/* The event wall reads better beside its three points than under them. */
.feat-show-split { display: grid; grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr); gap: 34px; align-items: start; }
/* app.css lays these out as `repeat(3, 1fr)` for the homepage's wide copy
   column. Beside the wall they stack, so the columns have to be overridden
   explicitly — setting only `display:grid` and `gap` left the three-column
   template in place and the row unchanged. Override the property you actually
   mean, not its neighbour. */
.feat-show-split .events-points { display: grid; grid-template-columns: 1fr; align-content: start; gap: 12px; margin-top: 0; }
.feat-show-aside { display: grid; align-content: start; gap: 18px; }
.feat-show-aside > p { margin: 0; color: var(--muted, #5b6155); font-size: 16px; line-height: 1.7; }
.feat-show-aside .events-action { margin-top: 4px; }
.feat-show-single { display: grid; justify-items: center; }
.feat-show-single .profile-browser { width: 100%; max-width: 760px; }
@media (max-width: 900px) { .feat-show-split { grid-template-columns: 1fr; gap: 26px; } }
@media (max-width: 700px) { .feat-show { padding: 46px 0 6px; } .feat-show-head { margin-bottom: 26px; } }

/* --- Body ---------------------------------------------------------------- */
.feat-body { padding: 78px 0 20px; background: var(--paper, #f4f1eb); }
.feat-sections { display: grid; gap: 18px; }

/* One card per point. The PHP still emits <section><h2><p>…, so the copy did
   not have to be rewritten to change how it reads. */
.feat-section {
  padding: 34px 34px 30px;
  border: 1px solid var(--line, rgba(17,19,15,.1));
  border-radius: 20px;
  background: #fff;
  /* Grid items default to min-width:auto, which means "at least as wide as my
     content" — so the 760px comparison table stretched its card to 762px at a
     390px viewport and pushed the whole page out to 815px instead of scrolling
     inside .cmp-scroll. Measured, not theorised. min-width:0 lets the card
     shrink and hands the overflow back to the scroller where it belongs. */
  min-width: 0;
}
.feat-section > h2 {
  margin: 0 0 14px;
  font-family: var(--display, Georgia, serif);
  font-size: clamp(22px, 2.6vw, 29px);
  line-height: 1.18;
  letter-spacing: -.01em;
  color: var(--ink, #11130f);
}
.feat-section > p { margin: 0 0 13px; color: var(--muted, #5b6155); font-size: 16.5px; line-height: 1.72; }
.feat-section > p:last-child { margin-bottom: 0; }
.feat-section a { color: var(--green, #304720); font-weight: 600; }
/* A standalone action on its own line, not a link inside a sentence, so
   WCAG 2.5.8's inline exemption does not cover it — these measured 20px.
   min-height plus inline-flex rather than padding, so the text baseline does
   not move relative to the paragraphs around it. */
.feat-inline-action { display: inline-flex; align-items: center; gap: 7px; min-height: 24px; font-weight: 700; }
.feat-inline-action svg { width: 16px; height: 16px; }
.feat-section ul { margin: 0; padding-left: 20px; display: grid; gap: 10px; color: var(--muted, #5b6155); font-size: 16.5px; line-height: 1.7; }

/* A numbered rail down the left of each card. Decorative and counter-driven, so
   adding or removing a section in the PHP renumbers everything automatically —
   a hand-typed number would go stale the first time a section moved. Hidden
   from assistive tech: the heading already carries the meaning. */
.feat-sections { counter-reset: feat; }
.feat-section { position: relative; counter-increment: feat; }
.feat-section::before {
  content: counter(feat, decimal-leading-zero);
  position: absolute;
  top: 34px;
  left: -62px;
  color: var(--green, #304720);
  opacity: .38;
  font-family: var(--display, Georgia, serif);
  font-size: 20px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
/* The rail lives outside the card, so it can only exist where there is room
   beside the column. Below that it would overlap the card or push the grid
   sideways, which is why it is removed rather than repositioned. */
@media (max-width: 1080px) { .feat-section::before { display: none; } }

/* --- Plan cards (/pricing) ----------------------------------------------- */
/* Every number in here is rendered from pmTierPublicFacts(); this sheet only
   decides how they look. If a tier is ever added, the grid absorbs it. */
.feat-plans {
  margin-top: 24px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(196px, 1fr));
  gap: 14px;
}
.feat-plan {
  position: relative;
  display: grid;
  align-content: start;
  gap: 9px;
  padding: 22px 20px 20px;
  border: 1px solid var(--line, rgba(17,19,15,.1));
  border-radius: 16px;
  background: var(--paper, #f4f1eb);
}
/* One plan is outlined rather than colour-filled: a solid green card next to
   three pale ones reads as "already selected", not "recommended". */
.feat-plan-pick { border-color: var(--green, #304720); background: #fff; box-shadow: 0 0 0 1px var(--green, #304720) inset; }
.feat-plan-flag {
  position: absolute;
  top: -10px;
  left: 20px;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--green, #304720);
  color: #fff;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.feat-plan-name { font-size: 13px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--muted, #5b6155); }
.feat-plan-price { font-family: var(--display, Georgia, serif); font-size: 31px; line-height: 1; color: var(--ink, #11130f); }
.feat-plan-price small { font-size: 14px; font-family: inherit; color: var(--muted, #5b6155); }
.feat-plan-facts { margin: 4px 0 0; padding: 0; display: grid; gap: 8px; list-style: none; font-size: 14.5px; line-height: 1.5; color: var(--muted, #5b6155); }
.feat-plan-facts li { padding-left: 20px; position: relative; }
.feat-plan-facts li::before { content: '·'; position: absolute; left: 7px; font-weight: 800; color: var(--muted, #5b6155); }
/* The unmarked-photographs line is the one people are buying, so it gets the
   tick and the ink colour; the marked version stays a neutral bullet. */
.feat-plan-facts li.on { color: var(--ink, #11130f); font-weight: 600; }
.feat-plan-facts li.on::before { content: '✓'; left: 3px; font-size: 12px; color: var(--green, #304720); }

/* --- Related pages ------------------------------------------------------- */
.feat-more { padding: 30px 0 96px; background: var(--paper, #f4f1eb); }
.feat-more > h2 {
  margin: 0 0 22px;
  font-family: var(--display, Georgia, serif);
  font-size: clamp(24px, 3vw, 33px);
  letter-spacing: -.01em;
  color: var(--ink, #11130f);
}
.feat-more-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(272px, 1fr)); gap: 16px; }
.feat-more-card {
  display: grid;
  align-content: start;
  gap: 9px;
  padding: 24px 24px 22px;
  border: 1px solid var(--line, rgba(17,19,15,.1));
  border-radius: 18px;
  background: #fff;
  color: inherit;
  text-decoration: none;
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.feat-more-card:hover {
  transform: translateY(-3px);
  border-color: rgba(48,71,32,.34);
  box-shadow: 0 18px 44px rgba(17,19,15,.09);
}
.feat-more-card strong { font-family: var(--display, Georgia, serif); font-size: 19px; font-weight: 600; color: var(--ink, #11130f); }
.feat-more-card span { color: var(--muted, #5b6155); font-size: 14.5px; line-height: 1.6; }
.feat-more-card em { display: inline-flex; align-items: center; gap: 6px; color: var(--green, #304720); font-size: 13.5px; font-style: normal; font-weight: 800; }

/* --- Closing call to action ---------------------------------------------- */
.feat-cta { padding: 74px 0; background: var(--ink, #11130f); color: #fff; }
.feat-cta-inner { display: grid; gap: 16px; justify-items: center; max-width: 660px; margin-inline: auto; text-align: center; }
.feat-cta h2 { margin: 0; font-family: var(--display, Georgia, serif); font-size: clamp(28px, 4vw, 43px); line-height: 1.1; letter-spacing: -.02em; }
.feat-cta p { margin: 0; color: rgba(255,255,255,.74); font-size: 17px; line-height: 1.65; }
.feat-cta-actions { margin-top: 8px; display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; }

@media (max-width: 700px) {
  .feat-hero { min-height: 230px; padding: 84px 0 30px; }
  .feat-body { padding: 52px 0 16px; }
  .feat-section { padding: 26px 22px 24px; border-radius: 17px; }
  .feat-more { padding: 24px 0 68px; }
  .feat-cta { padding: 58px 0; }
}

/* ---------------------------------------------------------------------------
   Help centre (/faq).

   Ported from legal.css on 2026-08-13 when faq.php moved onto this shell. The
   behaviour is unchanged and still lives in assets/faq.js — the page renders
   every answer OPEN with `.faq-tools` hidden, and the script then collapses
   them and reveals the search. That contract is why the CSS must not hide
   anything itself: with JS off the page has to stay readable.
   --------------------------------------------------------------------------- */
.faq-sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.faq-tools { margin: 0 0 16px; }
.faq-search {
  position: relative; display: flex; align-items: center; gap: 10px;
  background: #fff; border: 1px solid var(--line); border-radius: 14px; padding: 0 16px;
  box-shadow: 0 1px 2px rgba(17,19,15,.04);
}
.faq-search:focus-within { border-color: var(--green); box-shadow: 0 0 0 3px rgba(48,71,32,.12); }
.faq-search svg { flex: 0 0 auto; color: var(--muted); }
/* 16px is deliberate and load-bearing: iOS Safari auto-zooms any focused input
   below it, which jerks the page mid-search on a phone. Do not "tidy" this. */
.faq-search input { flex: 1 1 auto; border: 0; background: none; padding: 15px 0; font: inherit; font-size: 16px; color: var(--ink); min-width: 0; }
.faq-search input:focus { outline: none; }
.faq-search input::-webkit-search-cancel-button { display: none; }
.faq-clear { flex: 0 0 auto; border: 0; background: none; color: var(--muted); font-size: 22px; line-height: 1; cursor: pointer; padding: 0 2px; }
.faq-clear:hover { color: var(--ink); }
.faq-toolbar { display: flex; flex-wrap: wrap; gap: 8px 16px; align-items: center; justify-content: space-between; margin-top: 12px; min-height: 24px; }
.faq-count { margin: 0; color: var(--muted); font-size: 13.5px; }
.faq-toggle-all { border: 0; background: none; padding: 0; color: var(--green); font: inherit; display: inline-flex; align-items: center; min-height: 24px; font-size: 13.5px; font-weight: 700; cursor: pointer; }
.faq-toggle-all:hover { text-decoration: underline; }

.faq-jump { margin: 0 0 22px; display: flex; flex-wrap: wrap; gap: 8px; }
.faq-jump a {
  display: inline-flex; align-items: center; gap: 7px; min-height: 34px;
  background: #fff; border: 1px solid var(--line); border-radius: 999px; padding: 7px 15px;
  color: var(--ink); text-decoration: none; font-size: 13.5px; font-weight: 600;
  transition: border-color .15s ease, color .15s ease;
}
.faq-jump a:hover { border-color: var(--green); color: var(--green); }
.faq-jump span { color: var(--muted); font-weight: 500; font-size: 12.5px; }

/* Each topic group is a card, matching the feature pages' point cards. */
.faq-group { padding: 10px 30px 14px; border: 1px solid var(--line); border-radius: 20px; background: #fff; }
.faq-group > h2 {
  margin: 20px 0 4px;
  font-family: var(--display, Georgia, serif);
  font-size: clamp(20px, 2.3vw, 26px);
  letter-spacing: -.01em;
  color: var(--ink);
}
.faq-item { border-top: 1px solid var(--line); }
.faq-item:first-of-type { border-top: 0; }
.faq-item h3 { margin: 0; }
.faq-q {
  display: flex; width: 100%; gap: 16px; align-items: flex-start; justify-content: space-between;
  border: 0; background: none; padding: 16px 0; margin: 0; font: inherit;
  font-size: 16px; font-weight: 800; color: var(--ink); text-align: left; cursor: pointer;
}
.faq-q:hover { color: var(--green); }
.faq-q:focus-visible { outline: 2px solid var(--green); outline-offset: 3px; border-radius: 6px; }
.faq-q svg { flex: 0 0 auto; margin-top: 2px; color: var(--muted); transition: transform .18s ease; }
.faq-item.open .faq-q svg { transform: rotate(180deg); }
.faq-a { padding: 0 0 18px; color: var(--muted); font-size: 16px; line-height: 1.7; }
.faq-a p { margin: 0 0 12px; }
.faq-a p:last-child { margin-bottom: 0; }
.faq-a a { color: var(--green); font-weight: 600; }
.faq-a code { background: #f1efe9; border-radius: 4px; padding: 1px 5px; font-size: .92em; }
.faq-empty { margin: 0 0 20px; color: var(--muted); }

@media (max-width: 700px) {
  .faq-group { padding: 6px 20px 10px; border-radius: 17px; }
  .faq-q { font-size: 15.5px; gap: 12px; }
}
@media (prefers-reduced-motion: reduce) { .faq-q svg { transition: none; } }

/* ---------------------------------------------------------------------------
   Comparison tables (/pixieset-alternative and friends).

   Moved here from legal.css on 2026-08-13 — feature.php was their only user,
   and it no longer loads that sheet. Behaviour is unchanged: on a wide screen
   the table breaks out of the text column, and on a phone it keeps its real
   width and SCROLLS inside its own wrapper, the same pattern the admin tables
   use. Shrinking columns to fit turns a comparison into unreadable confetti.
   --------------------------------------------------------------------------- */
/* The breakout is gone. It existed to escape legal.css's 820px reading column
   with a negative margin computed from that exact number; the card now sits in
   a .content-shell (min(1160px, 100vw - 64px)), so the same negative margin
   would drag the table out past the page gutter. The card is wide enough. */
.cmp-wide { max-width: 100%; }
.cmp-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; border: 1px solid var(--line); border-radius: 14px; background: #fff; }
.cmp-table { border-collapse: collapse; width: 100%; min-width: 760px; font-size: 15px; }
.cmp-table th, .cmp-table td { padding: 12px 14px; text-align: left; vertical-align: top; border-bottom: 1px solid var(--line); }
.cmp-table thead th {
  position: sticky; top: 0; z-index: 1;
  background: #fff;
  font-size: 13px; letter-spacing: .02em; text-transform: uppercase; color: var(--muted);
  border-bottom: 2px solid var(--line);
}
.cmp-table tbody tr:last-child th, .cmp-table tbody tr:last-child td { border-bottom: 0; }
.cmp-table tbody th { font-weight: 650; color: var(--ink); white-space: nowrap; }
.cmp-table td { color: var(--muted); }
/* The PixMedium column, tinted end to end so the eye can follow it down a long
   table without re-reading the header every row. */
.cmp-table .cmp-us { background: rgba(197,215,184,.28); color: var(--ink); font-weight: 600; }
.cmp-table thead .cmp-us { background: var(--green); color: #fff; border-bottom-color: var(--green); }
.cmp-yes { color: var(--green); font-weight: 750; }
.cmp-no { color: var(--muted); }
.cmp-note { margin: 10px 2px 0; font-size: 13.5px; color: var(--muted); }
.cmp-note a { color: var(--green); }
