/**
 * Landing page content styles — the single source of truth.
 *
 * Loaded by BOTH:
 *   • public/landing-page.html   — what a visitor sees
 *   • the editor preview in public/admin-mailing.html (inline + full-page)
 *
 * These used to be two separate copies, and they had already drifted: the
 * public page collapsed multi-column grids on mobile and the editor preview
 * did not, so the preview showed a layout visitors never got. A preview that
 * renders through different CSS than the real page is worse than no preview,
 * because it is confidently wrong. Change this file and both sides move
 * together — do not re-inline these rules anywhere.
 */

:root {
  --lp-bg: #FFFCF5;
  --lp-text: #2C2C2C;
  --lp-muted: #6F6B66;
  --lp-heading: #8B1A1A;
  --lp-accent: #5C3670;
  --lp-line: #E4E1DB;
  --lp-success: #2E7D32;
  /* Horizontal padding of the content card. Full-bleed sections cancel it out
     by exactly this much, so the two must stay defined in one place. */
  --lp-pad: 44px;
}

/* ── Page background ─────────────────────────────────────────────────────
   Deliberately NOT scoped to .lp-container: the background belongs to the
   page, and the container is a 760px column in the middle of it. Publicly the
   attribute goes on <body>; in the editor it goes on the canvas shell, which
   is what stands in for the page there. One rule set, two hosts — so a
   background chosen in the editor is the background a visitor gets.
   A custom colour or an image is applied inline by both, on the same element. */
[data-page-bg="white"]     { background: #FFFFFF; }
[data-page-bg="cream"]     { background: #FFFCF5; }
[data-page-bg="sand"]      { background: #F6F3EE; }
[data-page-bg="purple"]    { background: #F3EEF6; }
[data-page-bg="gold"]      { background: #FAF5EC; }
[data-page-bg="bordeaux"]  { background: #F9EFEF; }
[data-page-bg="dark"]      { background: #2C2A33; }
[data-page-bg="grad-purple"] { background: linear-gradient(160deg, #F3EEF6 0%, #FFFCF5 55%, #F6F3EE 100%); }
[data-page-bg="grad-warm"]   { background: linear-gradient(160deg, #FAF5EC 0%, #FFFCF5 50%, #F9EFEF 100%); }
[data-page-bg="grad-dusk"]   { background: linear-gradient(160deg, #E9DFEC 0%, #F6F3EE 60%, #FBF3F3 100%); }
/* A gradient must not repeat when the page is longer than the screen. */
[data-page-bg^="grad-"] { background-attachment: fixed; background-size: cover; }
/* On dark, the text of a page without its own card has to invert. */
[data-page-bg="dark"] .lp-footer, [data-page-bg="dark"] .lp-loading { color: #C9C4CE; }

/* A background image sits under everything; the mode decides how it behaves. */
[data-page-bg-mode="cover"]  { background-size: cover; background-position: center; background-repeat: no-repeat; background-attachment: fixed; }
[data-page-bg-mode="repeat"] { background-repeat: repeat; background-size: auto; }
[data-page-bg-mode="top"]    { background-size: contain; background-position: top center; background-repeat: no-repeat; }

.lp-container { max-width: 760px; margin: 0 auto; padding: 40px 24px 80px; }
/* Page width. The default column is sized for reading; "wide" and "full" exist
   for pages that are mostly imagery or multi-column sections, where a narrow
   column wastes the screen. Text at full width past ~1100px becomes hard to
   read, which is why "full" is opt-in per page and not the default. */
.lp-container[data-page-width="wide"] { max-width: 1100px; }
.lp-container[data-page-width="full"] { max-width: none; padding-inline: 32px; }

.lp-content {
  background: #fff;
  border-radius: 18px;
  padding: 48px var(--lp-pad);
  box-shadow: 0 4px 24px rgba(0,0,0,0.05);
  border: 1px solid var(--lp-line);

  /* The base typography lives HERE, not on the public page's <body>, because
     the editing canvas is not that body — it is a Quill root, and quill.snow.css
     sets its own line-height (1.42), text-align (left) and white-space
     (pre-wrap). Left implicit, the canvas rendered tighter, left-aligned and
     with spaces preserved, none of which matches the published page. Stating
     the base on .lp-content gives both environments the same starting point
     from one file. */
  font-family: 'Assistant', system-ui, sans-serif;
  color: var(--lp-text);
  line-height: 1.7;
  font-size: 16px;
  text-align: start;
  white-space: normal;
}

/* Clip full-bleed sections to the card's rounded corners — but only on pages
   that actually contain one. Applying overflow:hidden to every .lp-content
   would silently crop imported pages whose own design relies on overflowing
   (sticky bars, decorative elements, negative margins), and there is already a
   published imported page in the wild. Scope the side effect to the feature
   that needs it. */
.lp-content:has(.ph-section[data-width="full"]) { overflow: hidden; }

.lp-content h1, .lp-content h2, .lp-content h3, .lp-content h4 {
  color: var(--lp-heading); margin: 24px 0 12px; line-height: 1.3;
}
.lp-content h1 { font-size: 30px; }
.lp-content h2 { font-size: 24px; }
.lp-content h3 { font-size: 20px; }
.lp-content p { margin: 0 0 14px; font-size: 16px; }
.lp-content a { color: var(--lp-accent); }
.lp-content img { max-width: 100%; height: auto; border-radius: 8px; margin: 12px 0; }

/* Image size. Percentages rather than pixels so an image keeps its proportion
   of the column whatever the screen does. Alignment is separate from size:
   a half-width image can sit right, centre or left. */
/* Size comes from a custom property, not from the width itself. Fixed steps
   could not answer "still too big" — the closest smaller step was 25 points
   away — and a free value written as an inline `width` would beat the mobile
   rule, which is the one rule that must always win. A variable keeps the
   cascade usable: the page sets it, the phone overrides it. */
.lp-content img[data-w] { width: var(--img-w, 100%); }
.lp-content img[data-w="25"]  { --img-w: 25%; }
.lp-content img[data-w="50"]  { --img-w: 50%; }
.lp-content img[data-w="75"]  { --img-w: 75%; }
.lp-content img[data-w="100"] { --img-w: 100%; }
/* Height, when the author wants a band rather than the whole picture. */
.lp-content img[data-h] { height: var(--img-h, auto); object-fit: cover; }

/* Width in pixels. A percentage is measured against a container the author
   cannot see, so "150%" meant one thing in a narrow cell and something enormous
   on a full-width page — the same number, wildly different pictures. A pixel
   width is the size you asked for, and max-width keeps it inside whatever it
   lands in, so it can never overflow. */
.lp-content img[data-unit="px"] {
  width: var(--img-w);
  max-width: 100%;
  margin-inline: 0;
}
.lp-content img[data-unit="px"][data-align="center"] { margin-inline: auto; }
.lp-content img[data-unit="px"][data-align="left"] { margin-inline-start: auto; margin-inline-end: 0; }
.lp-content img[data-align="center"] { display: block; margin-inline: auto; }
.lp-content img[data-align="left"] { display: block; margin-inline-start: auto; }

/* Larger than the column it sits in. The width alone is not enough: at 150%
   the image would simply overflow to one side, which reads as a mistake. The
   negative margin is exactly half the overflow, so the picture bleeds evenly
   past both edges and stays centred on the text it belongs to.
   These come AFTER the alignment rules on purpose — at more than full width
   there is no alignment left to choose, and the bleed has to win the tie. */
/* Past full width the overflow is split evenly, so the picture bleeds the same
   amount on both sides and stays centred on the text it belongs to. calc()
   means this works for any value the slider produces, not just three. */
.lp-content img[data-w][data-bleed] {
  max-width: none; display: block;
  margin-inline: calc((100% - var(--img-w, 100%)) / 2);
}

/* …but not when there is a neighbour to cover. Inside a grid with more than one
   column, an image that bleeds past its cell lands on top of the cell beside
   it: 125% of a narrow cell then reads as an image spanning the whole row,
   which is why the numbers stopped meaning anything. Where a bleed would
   destroy the layout it is simply not applied, and the cell is the frame. */
.lp-content .ph-grid:not([data-cols="1"]) > .ph-cell img[data-bleed],
.lp-content .ph-columns > * img[data-bleed] {
  --img-w: 100%; max-width: 100%; margin-inline: 0;
}
.lp-content blockquote {
  border-right: 4px solid var(--lp-accent); padding: 8px 16px; margin: 16px 0;
  color: var(--lp-muted); font-style: italic; background: #f9f8f3; border-radius: 6px;
}
.lp-content ul, .lp-content ol { padding-right: 24px; margin: 12px 0; }
.lp-content li { margin: 6px 0; }

/* CTA buttons inserted via the editor toolbar */
.lp-content a.cta-btn {
  display: inline-block; background: var(--lp-accent); color: #fff !important;
  padding: 12px 28px; border-radius: 10px; text-decoration: none;
  font-weight: 700; font-size: 15px; margin: 8px 4px; transition: background .15s;
}
.lp-content a.cta-btn:hover { background: #4a2a5b; }
.lp-content a.cta-btn.secondary { background: #fff; color: var(--lp-accent) !important; border: 2px solid var(--lp-accent); padding: 10px 26px; }
.lp-content a.cta-btn.gold { background: #c4a882; color: #fff !important; }
.lp-content a.cta-btn.gold:hover { background: #a98c64; }
.lp-content a.cta-btn.deep { background: #8B1A1A; color: #fff !important; }
.lp-content a.cta-btn.deep:hover { background: #6e1414; }

/* ── Sections: the vertical axis ─────────────────────────────────────────── */
/* Horizontal margin and padding come from variables so the width variants set
   ONE thing each. Previously the base rule used the `margin`/`padding`
   shorthands and the variants used the logical `margin-inline`/`padding-inline`
   longhands — two declarations fighting over the same computed value, which is
   fragile and hard to reason about. Now there is nothing to override. */
.lp-content .ph-section {
  border-radius: 10px;
  padding: 20px var(--ph-sec-px, 24px);
  margin: 18px var(--ph-sec-mx, 0);
}
.lp-content .ph-section[data-bg="cream"]    { background: #FFFCF5; border: 1px solid var(--lp-line); }
.lp-content .ph-section[data-bg="purple"]   { background: rgba(92, 54, 112, 0.08); }
.lp-content .ph-section[data-bg="gold"]     { background: rgba(196, 168, 130, 0.12); }
.lp-content .ph-section[data-bg="bordeaux"] { background: rgba(139, 26, 26, 0.08); }

/* Section width. "wide" eats the card's own padding; "full" spans the whole
   card edge to edge. Both keep their inner text padded so nothing touches the
   edge. */
/* wide: breaks halfway out of the card's padding, keeps its rounded corners.
   full: flush with the card edge, square corners — unmistakably different from
   wide, which the old -0.6 / -1 pair was not. */
.lp-content .ph-section[data-width="wide"] {
  --ph-sec-mx: calc(var(--lp-pad) * -0.5);
  --ph-sec-px: calc(var(--lp-pad) * 0.5 + 24px);
}
.lp-content .ph-section[data-width="full"] {
  --ph-sec-mx: calc(var(--lp-pad) * -1);
  --ph-sec-px: var(--lp-pad);
  border-radius: 0;
}

/* Text inside a section is ordinary page text: same sizes, same link colour,
   same list indent. The editor writes <font size> and inline colours, which
   browsers still honour — these rules only make sure nothing that lives inside
   a section is left unstyled because it sits in a nested container. */
.lp-content .ph-section p { margin: 0 0 12px; font-size: 16px; }
.lp-content .ph-section a { color: var(--lp-accent); }
.lp-content .ph-section ul,
.lp-content .ph-section ol { padding-right: 22px; margin: 10px 0; }
.lp-content .ph-section li { margin: 5px 0; }
.lp-content .ph-section h4 { color: var(--lp-accent); font-size: 16px; margin: 0 0 8px; }
.lp-content .ph-section p:last-child { margin-bottom: 0; }

/* Text sizes chosen in the section editor. Relative on purpose: <font size="4">
   means 18px in every browser regardless of its surroundings, so a sized run
   stopped tracking the page — it looked like the font had changed by itself.
   In em, "large" stays large next to a heading and next to body text alike. */
.lp-content .ph-fs-xs { font-size: 0.75em; }
.lp-content .ph-fs-sm { font-size: 0.85em; }
.lp-content .ph-fs-lg { font-size: 1.25em; }
.lp-content .ph-fs-xl { font-size: 1.6em; }

/* ── Columns: the horizontal axis ────────────────────────────────────────── */
.lp-content .ph-columns {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  /* A ceiling on how far apart columns may be pushed. On a page set to "full"
     the card is as wide as the screen, so two columns became two tracks of
     ~800px each: a small image pinned to one screen edge, a paragraph pinned to
     the other, and a canyon between them — with text lines far too long to
     read. Full width is for the BACKGROUND of a section; the content inside it
     still has to be readable. Below 1100px this changes nothing at all. */
  max-width: 1100px;
  margin: 16px auto;
  align-items: start;
}
/* min-width:0 stops a long word or wide image from blowing the track out. */
.lp-content .ph-columns > * { min-width: 0; padding: 0; }

/* Where a column's content sits horizontally, WITHOUT touching how its text is
   aligned. Centring a block and centring its text are different things: a
   narrow centred block whose text stays right-aligned is the common Hebrew
   layout, and text-align:center cannot express it. */
.lp-content .ph-columns > [data-place="center"] { margin-inline: auto; }
.lp-content .ph-columns > [data-place="left"]   { margin-inline-start: auto; }
.lp-content .ph-section > [data-place="center"] { margin-inline: auto; }
.lp-content .ph-section > [data-place="left"]   { margin-inline-start: auto; }
/* A centred block only reads as centred if it is narrower than its track — a
   full-width block is, by definition, already where it can be.
   max-content alone was not enough: for a paragraph, max-content is the width
   of the line WITHOUT wrapping, always wider than the column, so the cell kept
   filling the track and the auto margins had nothing to distribute. It looked
   like the setting did nothing for text and worked for images, which reads as
   random. min() takes whichever is narrower: short content hugs itself, a long
   paragraph is held to 80% and is then visibly off the edge it left. */
.lp-content [data-place="center"],
.lp-content [data-place="left"] { max-width: min(max-content, 80%); }

/* Vertical placement of the columns inside a section. Default is "start":
   columns that begin together read as a row. "center" and "end" matter when
   columns have very different heights — an image beside a short paragraph. */
.lp-content .ph-columns[data-valign="center"] { align-items: center; }
.lp-content .ph-columns[data-valign="end"]    { align-items: end; }
.lp-content .ph-columns[data-valign="stretch"] { align-items: stretch; }

.lp-content .ph-columns[data-cols="1"]   { grid-template-columns: 1fr; }
.lp-content .ph-columns[data-cols="2"]   { grid-template-columns: 1fr 1fr; }
.lp-content .ph-columns[data-cols="3"]   { grid-template-columns: repeat(3, 1fr); }
.lp-content .ph-columns[data-cols="4"]   { grid-template-columns: repeat(4, 1fr); }
.lp-content .ph-columns[data-cols="2-1"] { grid-template-columns: 2fr 1fr; }
.lp-content .ph-columns[data-cols="1-2"] { grid-template-columns: 1fr 2fr; }

/* A section whose background is a colour the author picked, or an image.
   Both exist because the imported pages use them: 16 sections carry an
   arbitrary hex and 7 carry a photograph. Without these the import had to
   round every background to one of four presets, which is not a conversion —
   it is a redesign nobody asked for. */
.lp-content .ph-section[data-bg="custom"] { background: var(--ph-sec-bg, transparent); }
.lp-content .ph-section[data-bg-image] {
  background-image: var(--ph-sec-img);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  position: relative;
}
/* Text over a photograph needs a floor under it, or it is legible only on the
   half of the image that happens to be dark. */
.lp-content .ph-section[data-bg-image][data-bg-overlay]::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: rgba(0, 0, 0, var(--ph-sec-overlay, .35));
  pointer-events: none;
}
.lp-content .ph-section[data-bg-image] > * { position: relative; z-index: 1; }
.lp-content .ph-section[data-bg-image][data-bg-overlay],
.lp-content .ph-section[data-bg-image][data-bg-overlay] h1,
.lp-content .ph-section[data-bg-image][data-bg-overlay] h2,
.lp-content .ph-section[data-bg-image][data-bg-overlay] h3,
.lp-content .ph-section[data-bg-image][data-bg-overlay] h4,
.lp-content .ph-section[data-bg-image][data-bg-overlay] p { color: #fff; }
.lp-content .ph-section[data-min-h] { min-height: var(--ph-sec-minh, 0); display: flex; flex-direction: column; justify-content: center; }

/* ── The grid ────────────────────────────────────────────────────────────
   Chosen like a table — rows × columns — and every cell edited on its own.
   This is a different idea from a section: a section is one block with a
   background and a fixed column layout, and editing it means opening a form
   that describes the WHOLE thing. A grid is a container of independent cells,
   so a change to one cell is a change to one cell.
   Columns and rows are explicit, so the layout does not have to be inferred
   from how many children happen to be inside. */
.lp-content .ph-grid {
  display: grid;
  gap: var(--ph-grid-gap, 18px);
  margin: 18px 0;
  grid-template-columns: repeat(var(--ph-grid-cols, 2), minmax(0, 1fr));
}
.lp-content .ph-grid[data-cols="1"] { --ph-grid-cols: 1; }
.lp-content .ph-grid[data-cols="2"] { --ph-grid-cols: 2; }
.lp-content .ph-grid[data-cols="3"] { --ph-grid-cols: 3; }
.lp-content .ph-grid[data-cols="4"] { --ph-grid-cols: 4; }
.lp-content .ph-grid[data-cols="5"] { --ph-grid-cols: 5; }
.lp-content .ph-grid[data-cols="6"] { --ph-grid-cols: 6; }
.lp-content .ph-grid[data-gap="none"]  { --ph-grid-gap: 0; }
.lp-content .ph-grid[data-gap="small"] { --ph-grid-gap: 8px; }
.lp-content .ph-grid[data-gap="large"] { --ph-grid-gap: 32px; }
.lp-content .ph-grid > .ph-cell { min-width: 0; }
.lp-content .ph-grid > .ph-cell > :last-child { margin-bottom: 0; }
/* Optional cell chrome, so a grid can read as a table when that is the point. */
.lp-content .ph-grid[data-style="bordered"] > .ph-cell { border: 1px solid var(--lp-line); border-radius: 8px; padding: 14px; }
.lp-content .ph-grid[data-style="cards"] > .ph-cell {
  background: #fff; border: 1px solid var(--lp-line); border-radius: 12px;
  padding: 18px; box-shadow: 0 2px 10px rgba(0,0,0,.04);
}
.lp-content .ph-grid[data-style="striped"] > .ph-cell:nth-child(even) { background: #FAF8F4; border-radius: 6px; padding: 12px; }
.lp-content .ph-grid[data-valign="center"] > .ph-cell { align-self: center; }
.lp-content .ph-grid[data-valign="end"] > .ph-cell { align-self: end; }

/* A row of social links. The imported pages drew these with Rav-Page's icon
   font, which does not exist here — so they arrive as our own inline SVG,
   the same paths the site footer uses. */
.lp-content .ph-social { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; margin: 20px 0; }
.lp-content .ph-social a {
  width: 44px; height: 44px; border-radius: 10px; background: var(--lp-heading);
  display: inline-flex; align-items: center; justify-content: center;
  text-decoration: none; transition: transform .15s, background .15s;
}
.lp-content .ph-social a:hover { transform: translateY(-2px); background: var(--lp-accent); }
.lp-content .ph-social svg { width: 22px; height: 22px; fill: #fff; }

/* A layer hidden in the tree is hidden for the visitor too. Hiding that only
   applied while editing would be a switch that lies: the page would keep
   showing the block to everyone except the person who turned it off. */
.lp-content [data-hidden="1"] { display: none; }

.lp-content .ph-divider { border: none; border-top: 2px solid var(--lp-line); margin: 28px 0; }
.lp-content .ph-spacer { display: block; height: 32px; }

.lp-content .ph-feature {
  display: flex; align-items: flex-start; gap: 16px; margin: 14px 0;
  padding: 14px; background: rgba(92, 54, 112, 0.04); border-radius: 10px;
}
.lp-content .ph-feature .icon { font-size: 32px; flex-shrink: 0; line-height: 1; }

.lp-content .ph-testimonial {
  background: #fff; border: 1px solid var(--lp-line); border-radius: 12px;
  padding: 22px 24px; margin: 16px 0; box-shadow: 0 2px 10px rgba(0,0,0,0.04);
}
.lp-content .ph-testimonial cite {
  display: block; margin-top: 12px; font-size: 13px; color: var(--lp-muted);
  font-style: normal; font-weight: 700;
}

.lp-content .ph-hero {
  text-align: center; padding: 36px 24px; border-radius: 14px;
  background: linear-gradient(135deg, rgba(92, 54, 112, 0.1), rgba(139, 26, 26, 0.06));
  margin: 18px 0;
}
.lp-content .ph-hero h1 { margin-top: 0; }

/* The shared footer template is written for email — table-based, fixed widths.
   These keep it sane on a page without touching the template itself. */
.lp-shared-footer { max-width: 760px; margin: 28px auto 0; }
.lp-shared-footer .footer,
.lp-shared-footer > div { border-radius: 12px; }
.lp-shared-footer img { margin: 0; }

/* ── Signup form widget ──────────────────────────────────────────────────── */
.ph-form {
  background: #fff; border: 1px solid var(--lp-line); border-radius: 14px;
  padding: 24px; max-width: 440px; margin: 20px auto; box-shadow: 0 4px 16px rgba(0,0,0,0.05);
}
.ph-form h3 { margin: 0 0 12px; text-align: center; }
.ph-form input[type=text], .ph-form input[type=tel], .ph-form input[type=email] {
  width: 100%; padding: 11px 14px; border: 1.5px solid var(--lp-line); border-radius: 8px;
  margin: 6px 0; font-family: inherit; font-size: 14px; background: #fff; color: #2C2C2C;
}
.ph-form input:focus { outline: none; border-color: var(--lp-accent); }
.ph-form button {
  width: 100%; padding: 13px; background: var(--lp-accent); color: #fff; border: none;
  border-radius: 8px; font-family: inherit; font-size: 15px; font-weight: 700;
  cursor: pointer; margin-top: 12px; transition: background .15s;
}
.ph-form button:hover:not(:disabled) { background: #4a2a5b; }
.ph-form button:disabled { opacity: .6; cursor: wait; }
.ph-form button.deep { background: #8B1A1A; }
.ph-form button.deep:hover:not(:disabled) { background: #6e1414; }
.ph-form button.gold { background: #c4a882; }
.ph-form button.gold:hover:not(:disabled) { background: #a98c64; }
.ph-form button.secondary { background: #fff; color: var(--lp-accent); border: 2px solid var(--lp-accent); }
.ph-form button.secondary:hover:not(:disabled) { background: var(--lp-accent); color: #fff; }
.ph-form .checkboxes { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 12px; margin: 8px 0; padding: 8px 0; }
.ph-form .checkboxes label { display: flex; align-items: center; gap: 8px; font-size: 13px; cursor: pointer; padding: 4px; }
.ph-form .checkboxes input { width: 18px; height: 18px; cursor: pointer; }
.ph-form .legal { font-size: 11px; color: var(--lp-muted); margin-top: 8px; line-height: 1.5; display: flex; gap: 8px; align-items: flex-start; cursor: pointer; }
.ph-form .legal input { margin-top: 2px; flex-shrink: 0; }
.ph-form .ph-form-msg { margin-top: 10px; padding: 10px; border-radius: 8px; font-size: 13px; text-align: center; display: none; }
.ph-form .ph-form-msg.success { background: #e0f0e3; color: var(--lp-success); border: 1px solid #8fc99d; display: block; }
.ph-form .ph-form-msg.error { background: #fce8e8; color: var(--lp-heading); border: 1px solid #f0c8c8; display: block; }

/* ── Narrow screens ──────────────────────────────────────────────────────── */
/* Four and three columns are unreadable on a tablet before they are unreadable
   on a phone, so they step down twice rather than once. */
@media (max-width: 900px) {
  .lp-content .ph-columns[data-cols="4"] { grid-template-columns: 1fr 1fr; }
  .lp-content .ph-columns[data-cols="3"] { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 600px) {
  :root { --lp-pad: 22px; }
  .lp-container { padding: 20px 12px 48px; }
  .lp-content { padding: 28px var(--lp-pad); border-radius: 12px; }
  .lp-content h1 { font-size: 25px; }
  .lp-content h2 { font-size: 21px; }

  /* A 25%-wide image on a phone is a thumbnail nobody can see. */
  .lp-content img[data-w] { --img-w: 100%; max-width: 100%; margin-inline: 0; }
  /* A pixel width already fits: max-width caps it. Forcing 100% here would
     blow a deliberately small logo up to the full width of the phone. */
  .lp-content img[data-unit="px"] { width: var(--img-w); max-width: 100%; }
  .lp-content img[data-h] { height: auto; }

  /* A grid collapses like everything else. Two columns on a 390px screen is
     two columns of nothing. One exception: a two-column grid of short cells
     often reads fine side by side, so it is kept at two below 4 columns only
     when the author asked for a tight gap — otherwise it stacks. */
  .lp-content .ph-grid { --ph-grid-cols: 1; }
  .lp-content .ph-grid[data-cols="2"][data-gap="small"],
  .lp-content .ph-grid[data-cols="2"][data-gap="none"] { --ph-grid-cols: 2; }

  .lp-content .ph-columns,
  .lp-content .ph-columns[data-cols="2"],
  .lp-content .ph-columns[data-cols="3"],
  .lp-content .ph-columns[data-cols="4"],
  .lp-content .ph-columns[data-cols="2-1"],
  .lp-content .ph-columns[data-cols="1-2"] {
    grid-template-columns: 1fr;
    gap: 16px;
  }

  /* Widget starters written before data-cols existed carry inline grid styles.
     Keep collapsing those too so old pages do not regress. */
  .lp-content [style*="grid-template-columns:1fr 1fr 1fr"],
  .lp-content [style*="grid-template-columns: 1fr 1fr 1fr"],
  .lp-content [style*="grid-template-columns:1fr 1fr"],
  .lp-content [style*="grid-template-columns: 1fr 1fr"] {
    grid-template-columns: 1fr !important;
    gap: 14px !important;
  }
  .ph-form .checkboxes { grid-template-columns: 1fr !important; }
}
