/*  Crystal Cleanse — landing design system
 *  =========================================================================
 *  Scoped to .cc so nothing leaks into Blocksy's header, footer or wp-admin.
 *  Custom properties namespaced --cc-* so they cannot collide with Blocksy's.
 *  border-left / padding-left converted to logical properties (RTL-ready).
 *
 *  READ THIS BEFORE ADDING A RULE
 *  -------------------------------------------------------------------------
 *  1. CLASS NAMES ARE PREFIXED, AND THE PROTOTYPE'S ARE NOT.
 *     The patterns emit cc-hero, cc-section, cc-center-head, cc-blog-foot,
 *     cc-news-small. The prototype (crystal-cleanse-landing-mineral-v4.html)
 *     calls the same things hero, section-pad, center-head, blog-foot and
 *     "news small". If you copy a rule across from the prototype you MUST
 *     translate the selector, or it will match nothing and fail silently.
 *     This exact mismatch shipped once and killed 18 rules — see README.
 *
 *     Not everything is prefixed: hero-grid, hero-cta, hero-photo,
 *     ritual, dark, saluxe, steps, crystal-grid, post, feat and the token
 *     names are identical in both. Check the live DOM, do not assume.
 *
 *  2. THERE ARE TWO STYLESHEETS AND THEY HAVE DIFFERENT JOBS.
 *     This file  = the design system. Anything that describes how the brand
 *                  looks: color, type, spacing, layout of the sections.
 *     style.css  = WordPress glue. Rules that exist only because of how
 *                  Gutenberg emits markup — Query Loop wrappers, button
 *                  resets, the content-size override. Put Gutenberg
 *                  workarounds there, not here.
 *
 *  3. THIS FILE'S ENQUEUE IS GUARDED ON PURPOSE.
 *     See the comment in functions.php. A hard-coded dependency on an
 *     unregistered handle makes WordPress drop the whole stylesheet without
 *     an error.
 *
 *  Dead rules for the phone mockups, the header and the footer were removed —
 *  the mockups ship as WebP images and Blocksy's builders own header/footer.
 *  All of it is still in the prototype if you ever need it back.
 */
.cc{--cc-surface:#F4F2F7;
  --cc-sage:#E9E4F0;
  --cc-sage-soft:#E9E4F0;
  --cc-card:#FFFFFF;

  /* Palette 2, issue #20. On sage, calculated contrast is 8.50:1 for gray
     and 5.20:1 for muted. Newsletter micro-copy keeps gray by decision 7. */
  --cc-ink:#1F1A27;
  --cc-session:#1C1426;
  --cc-on-dark-text:#F6F2FB;
  --cc-on-dark-muted:#DCD3E8;
  --cc-on-dark-subtle:#A89DB8;
  --cc-gray:#423C4B;
  --cc-muted:#625B6D;
  --cc-line:#E1DBE9;
  --cc-line-soft:#E1DBE9;
  /* Lines are decoration. An unfilled field or button uses controlBorder:
     calculated 3.96:1 on card, 3.56:1 on surface and 3.17:1 on sage.
     Line cannot outline a control (issue #20; brand/tokens.json). */
  --cc-control-border:#877A9E;

  /* A failed form send (6 October 2026; brand/tokens.json). A muted rose, not a
     signal red, so it sits beside the plum. The icon and border measure 6.08:1
     on error-soft and 6.67:1 on surface; ink text on error-soft is 13.94:1. */
  --cc-error:#9B2C42;
  --cc-error-soft:#F7E4E8;

  /* One plum accent from palette 2. Legacy custom-property names remain because
     the website CSS reads them; accent-soft is a decorative line only. */
  --cc-accent:#4B3A73;
  --cc-accent-soft:#E1DBE9;
  --cc-accent-on-dark:#CBB8EF;
  --cc-amethyst:#4B3A73;
  --cc-amethyst-soft:#CBB8EF;

  /* The retained band names now alias the two-stop palette-2 ramp, accent to
     session at 165deg. The middle stop is retired (decision 4, issue #20). */
  --cc-amethyst-deep:#1C1426;
  --cc-amethyst-mid:#4B3A73;
  --cc-amethyst-low:#1C1426;

  --cc-serif:'Newsreader', Georgia, 'Times New Roman', serif;
  --cc-sans:'Rethink Sans', system-ui, -apple-system, sans-serif;

  --cc-maxw:1180px;
  --cc-radius:18px;
  --cc-radius-lg:20px;
  --cc-ease:cubic-bezier(.22,.61,.36,1);}
/* ── Base / reset ── */
.cc *{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
.cc{font-family:var(--cc-sans);
  background:var(--cc-surface);
  color:var(--cc-ink);
  line-height:1.6;
  font-size:17px;
  overflow-x:hidden;}
.cc a{color:inherit;text-decoration:none}
.cc img,
.cc svg{display:block;max-width:100%}
.cc section{position:relative}
/* ── Typography ── */
.cc h1,
.cc h2,
.cc h3,
.cc h4{font-family:var(--cc-serif);font-weight:400;line-height:1.06;letter-spacing:-.01em;color:var(--cc-ink);text-wrap:balance}
/* All three limits are load-bearing and were measured — see CLAUDE.md decision
   8. Newsreader runs wider than v3's Fraunces, so the accent phrase "Clear your
   energy." splits in two the moment h1 outgrows its column, which kills the
   payoff of the hero.
     max 4.5rem  governs above ~1180px, where the container stops growing
     slope 6.2vw governs 980–1180px, where it does not. Do NOT raise this to
                 6.4vw: the fixed 28px gutter tightens the column faster than
                 the type, and at 1088px the column takes <=68px while 6.4vw
                 renders 69.6px. (The port shipped 6.4vw for a while; restored.)
     the 760px override below handles phones, where the 2.9rem floor is itself
                 wider than the column. */
.cc h1{font-size:clamp(2.9rem,6.2vw,4.5rem);font-optical-sizing:auto}
.cc h2{font-size:clamp(35px,4.2vw,52px)}
.cc h3{font-size:24px}
.cc em{font-style:italic;color:var(--cc-amethyst)}
.cc .eyebrow{font-family:var(--cc-sans);font-weight:600;font-size:14px;
  letter-spacing:.22em;text-transform:uppercase;color:var(--cc-accent);}
.cc .lead{color:var(--cc-gray);font-size:clamp(21px,1.4vw,24px);line-height:1.65;max-width:46ch}
.cc .muted{color:var(--cc-muted)}
/* ── Section rhythm ── */
.cc .cc-section{padding:clamp(72px,11vw,144px) 0}
/* ── Buttons ── */
.cc .btn{display:inline-flex;align-items:center;gap:8px;
  font-family:var(--cc-sans);font-weight:600;font-size:17px;
  padding:16px 28px;border-radius:14px;cursor:pointer;border:1.5px solid transparent;
  transition:transform .35s var(--cc-ease), background .3s var(--cc-ease), color .3s var(--cc-ease), box-shadow .35s var(--cc-ease);}
.cc .btn-primary{background:var(--cc-accent);color:var(--cc-card);box-shadow:0 14px 30px -16px rgba(31,26,39,.6)}
.cc .btn-primary:hover{background:var(--cc-ink);transform:translateY(-2px);box-shadow:0 20px 38px -16px rgba(31,26,39,.7)}
.cc .btn-ghost{background:transparent;color:var(--cc-ink);border-color:var(--cc-control-border)}
.cc .btn-ghost:hover{border-color:var(--cc-ink);transform:translateY(-2px)}
.cc .btn-light{background:var(--cc-on-dark-text);color:var(--cc-ink)}
/* .btn-ghost's border, --cc-control-border, is meant for light grounds.
   This is its counterpart for the amethyst band.
   The .45 alpha of onDarkText calculates to 3.15:1 against the plum stop,
   the weakest specified point. Rendered pixels behind the button still need
   checking because the glow can alter that contrast (issue #20). */
.cc .btn-ghost-on-dark{background:transparent;color:var(--cc-on-dark-text);border-color:rgba(246,242,251,.45)}
.cc .btn-ghost-on-dark:hover{background:rgba(246,242,251,.08);border-color:rgba(246,242,251,.6);transform:translateY(-2px)}
.cc .btn-light:hover{transform:translateY(-2px);box-shadow:0 16px 34px -18px rgba(31,26,39,.5)}
/* Arrow affordance ------------------------------------------------------------
   In the prototype this was a literal <span class="arr">→</span> inside the
   button. It cannot be markup here:
     - wp:read-more's "content" attribute is a plain string and cannot hold a
       span at all;
     - a custom span inside core/button's rich text risks tripping Gutenberg's
       block validation ("this block contains unexpected or invalid content").
   Both .btn and .post .read are inline-flex with a gap, so a ::after becomes a
   flex item and inherits that gap exactly as the span did — same spacing, same
   hover slide, no markup.

   These four are the only places the prototype puts an arrow. It CANNOT key off
   .btn-primary alone: the newsletter's "Join the List" is also .btn-primary and
   deliberately has none. .btn-ghost never carries one either. */
.cc .hero-cta .btn-primary::after,
.cc .saluxe-cta .btn-light::after,
.cc .contact-form .btn-primary::after,
.cc .cc-about-cta-buttons .btn-light::after,
.cc .post .read::after{content:"→";transition:transform .35s var(--cc-ease)}
.cc .hero-cta .btn-primary:hover::after,
.cc .saluxe-cta .btn-light:hover::after,
.cc .contact-form .btn-primary:hover::after,
.cc .cc-about-cta-buttons .btn-light:hover::after,
.cc .post:hover .read::after{transform:translateX(4px)}
/* The dark band's centered head is the one that must not reserve space beneath
   it — the band ends there. The prototype carried style="margin-bottom:0"
   inline; the port dropped it, leaving the default clamp(32px,6vw,72px). */
.cc .dark .cc-center-head{margin-bottom:0}
/* ── Hero ── */
/* The section is the photo's positioning context; its full-width box lets the
   photo reach the window edge while the text stays on the plain page ground. */
.cc .cc-hero{position:relative;padding-top:clamp(48px,7vw,88px);padding-bottom:clamp(56px,9vw,120px);overflow:hidden}
/* The grid's min-height gives the absolute photo its height: the prototype's
   1440×900 viewport calculated an 842px hero on 29 September 2026. */
.cc .hero-grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(32px,5vw,72px);align-items:center;min-height:clamp(520px,44vw,720px)}
.cc .cc-hero h1{margin:16px 0 12px}
.cc .cc-hero h1 .ln{display:block}
/* The eyebrow is quiet body text here so the headline carries the accent. */
.cc .cc-hero .eyebrow{font-size:17px;font-weight:500;letter-spacing:0;text-transform:none;color:var(--cc-muted)}
.cc .hero-cta{display:flex;gap:12px 24px;flex-wrap:wrap;align-items:center;margin:32px 0 0}
/* The published button markup lives in the WordPress database, so its ghost
   classes stay while this hero-specific rule draws it as a text link. */
.cc .hero-cta .btn-ghost{padding:0;border:0;background:none;box-shadow:none}
.cc .hero-cta .btn-ghost:hover{transform:none}
/* The link selector has specificity (0,5,0), and its :hover variant (0,6,0);
   both beat style.css's later (0,4,0) all: unset regardless of load order.
   The approved inline-block and 11px block padding were calculated for a
   44px target from a 22px line.
   Local Chromium instead measures a 27.2px inherited line and a 49.2px
   wrapper: the flex item blockifies. Its full-wrapper link ::after covers it. */
.cc .hero-cta .wp-block-button.btn-ghost .wp-block-button__link{display:inline-block;padding:11px 0;color:var(--cc-accent);text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:1px}
.cc .hero-cta .wp-block-button.btn-ghost .wp-block-button__link:hover{color:var(--cc-ink)}
/* ── Hero lifestyle photo ── */
/* Half the grid gap beyond its middle starts the photo exactly where the
   second column would; the section's right edge is the window edge. */
.cc .hero-photo{position:absolute;top:0;bottom:0;right:0;left:calc(50% + clamp(16px,2.5vw,36px))}
.cc .hero-photo .frame{margin:0;width:100%;height:100%;background:var(--cc-sage)}
/* The photo is a 4:5 master (2048×2560, live 29 September 2026) composed with
   the crystal and phone clear of the top and bottom 10%, so a centred crop
   serves every box: about 4:5 on laptops, near square at 1920px and on
   tablets. Replace it with another 4:5 image framed the same way. */
.cc .hero-photo .frame img{width:100%;height:100%;display:block;object-fit:cover;object-position:50% 50%}
/* ── Centered section heads ── */
.cc .cc-center-head{text-align:center;max-width:680px;margin:0 auto clamp(32px,6vw,72px)}
.cc .cc-center-head .eyebrow{display:block;margin-bottom:1rem}
.cc .cc-center-head .lead{margin:12px auto 0;text-align:center}
/* ── How it works ── */
.cc .steps{display:grid;grid-template-columns:repeat(3,1fr);gap:24px}
.cc .step{background:var(--cc-card);border:1px solid var(--cc-line-soft);border-radius:var(--cc-radius);padding:32px 32px;transition:transform .4s var(--cc-ease),box-shadow .4s var(--cc-ease)}
.cc .step:hover{transform:translateY(-4px);box-shadow:0 26px 50px -34px rgba(31,26,39,.26)}
.cc .step .num{font-family:var(--cc-serif);font-size:21px;color:var(--cc-accent);width:46px;height:46px;border:1px solid var(--cc-control-border);
  border-radius:50%;display:flex;align-items:center;justify-content:center;margin-bottom:20px}
.cc .step h3{margin-bottom:4px}
.cc .step p{font-size:17px;color:var(--cc-gray)}
/* ── Ritual (app) section ── */
/* Two sections share the sage ground: the app/ritual band and the blog band.
   In the prototype both literally carry class="ritual" — the blog section is
   <section class="section-pad ritual" id="blog">. The port renamed the blog
   one to cc-blog, and nothing styled it, so that band lost its background
   entirely and read as page-surface white.
   (The prototype's .ritual also sets overflow:hidden, per CLAUDE.md decision 9.
   Not carried over, and not needed: it existed to clip .phone-wrap::after, the
   glow behind the CSS phone mockups, which are flat WebP images in this port.) */
.cc .ritual,
.cc .cc-blog{background:var(--cc-sage)}
.cc .ritual-grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(40px,6vw,80px);align-items:center}
.cc .feat{list-style:none;margin-top:32px;display:grid;gap:16px}
/* NOTE: this flex row assumes [icon, text]. patterns/app-mockup.php emits no
   icon element, so style.css overrides li back to display:block. The .fi icon
   box that used to sit here was removed with the rest of the dead rules. */
/* Feature-list icons ----------------------------------------------------------
   The prototype puts a Lucide icon in a 34px tinted box before each item:
   <li><span class="fi"><svg/></span><div><b>Term</b><p>desc</p></div></li>.
   That structure does not survive the port — core/list-item is plain rich text
   and cannot hold a <span> wrapping an inline <svg> without risking Gutenberg
   block validation, and the page's markup lives in the database anyway.

   So the box and the icon are one ::before in the item's padding gutter. The
   masters are in sources/icons/ (Lucide, 24px, stroke 1.5). Inlined as data
   URIs rather than uploaded to the Media Library, deliberately:
     - WordPress blocks SVG uploads by default, for good reason; enabling them
       is a real security decision to take for 1.8 KB of icons;
     - as <img src> they lose stroke="currentColor" and render black instead of
       --cc-ink;
     - four files would be four requests.
   currentColor cannot resolve inside a background image either, so --cc-ink is
   baked in as #1F1A27. If that token ever changes, these must change with it.

   Order-coupled by :nth-child, because the list items carry no distinguishing
   class. The four items are fixed copy under the copy freeze; if that list is
   ever reordered, reorder these with it.
   Decorative only — as backgrounds they are correctly invisible to screen
   readers, since each item's text already carries the whole meaning. */
.cc .feat li{position:relative;padding-inline-start:48px;min-height:32px}
.cc .feat li::before{content:"";position:absolute;inset-inline-start:0;top:0;width:32px;height:32px;
  border-radius:14px;background-color:rgba(31,26,39,.06);
  background-repeat:no-repeat;background-position:center;background-size:24px 24px}
/* 1. Sound-based cleansing — sources/icons/sound_cleanse.svg */
.cc .feat li:nth-child(1)::before{background-image:url("data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22%231F1A27%22%20stroke-width=%221.5%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Cpath%20d=%22M2%2013a2%202%200%200%200%202-2V7a2%202%200%200%201%204%200v13a2%202%200%200%200%204%200V4a2%202%200%200%201%204%200v13a2%202%200%200%200%204%200v-4a2%202%200%200%201%202-2%22/%3E%3C/svg%3E")}
/* 2. Matched to your intention — sources/icons/intention.svg */
.cc .feat li:nth-child(2)::before{background-image:url("data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22%231F1A27%22%20stroke-width=%221.5%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Cpath%20d=%22M2%209.5a5.5%205.5%200%200%201%209.591-3.676.56.56%200%200%200%20.818%200A5.49%205.49%200%200%201%2022%209.5c0%202.29-1.5%204-3%205.5l-5.492%205.313a2%202%200%200%201-3%20.019L5%2015c-1.5-1.5-3-3.2-3-5.5%22/%3E%3C/svg%3E")}
/* 3. 3, 5 or 10 minutes — sources/icons/timer.svg */
.cc .feat li:nth-child(3)::before{background-image:url("data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22%231F1A27%22%20stroke-width=%221.5%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Cline%20x1=%2210%22%20x2=%2214%22%20y1=%222%22%20y2=%222%22/%3E%3Cline%20x1=%2212%22%20x2=%2215%22%20y1=%2214%22%20y2=%2211%22/%3E%3Ccircle%20cx=%2212%22%20cy=%2214%22%20r=%228%22/%3E%3C/svg%3E")}
/* 4. An immersive dark screen — sources/icons/immersive_dark_screen.svg */
.cc .feat li:nth-child(4)::before{background-image:url("data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22%231F1A27%22%20stroke-width=%221.5%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Cpath%20d=%22M18%205h4%22/%3E%3Cpath%20d=%22M20%203v4%22/%3E%3Cpath%20d=%22M20.985%2012.486a9%209%200%201%201-9.473-9.472c.405-.022.617.46.402.803a6%206%200%200%200%208.268%208.268c.344-.215.825-.004.803.401%22/%3E%3C/svg%3E")}
.cc .feat b{font-weight:600}
.cc .feat p{font-size:17px;color:var(--cc-gray);margin-top:4px}
/* ── Dark band ── */
.cc .dark{background:var(--cc-session);color:var(--cc-on-dark-text)}
.cc .dark h2,
.cc .dark h3{color:var(--cc-on-dark-text)}
.cc .dark .eyebrow{color:var(--cc-accent-on-dark)}
/* .cc em paints the light-ground accent by default. This dark band overrides it
   with accentOnDark; calculated 9.89:1 on session (issue #20). */
.cc .dark em{color:var(--cc-accent-on-dark)}
.cc .dark .lead{color:var(--cc-on-dark-muted)}
/* ── Crystals ── */
.cc .crystal-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:16px;margin-top:8px}
.cc .cx{display:flex;align-items:center;gap:12px;background:var(--cc-card);border:1px solid var(--cc-line-soft);
  border-radius:var(--cc-radius);padding:12px 16px;font-size:17px;font-weight:500}
.cc .cx .sw{width:18px;height:18px;border-radius:50%;flex:none;box-shadow:inset 0 0 0 1px rgba(31,26,39,.06)}
.cc .cx-more{display:flex;align-items:center;justify-content:center;gap:8px;background:transparent;border:1px dashed var(--cc-control-border);color:var(--cc-muted);font-size:14px}
/* The crystal chips are labels, not links, so they no longer lift on hover; only
   the "10 more in the app" cell is a link, to the web app, and only it answers the
   pointer (Henrik, 5 October 2026). */
.cc a.cx-more{transition:color .2s,border-color .2s}
.cc a.cx-more:hover{color:var(--cc-accent);border-color:var(--cc-accent)}
/* ── Blog ── */
/* `position:relative` is NOT decoration — it anchors .tag ------------------------
   In the prototype the tag pill sits inside .thumb, which is position:relative,
    so the tag's absolute top/left offset lands it on the image.
   That nesting is impossible here: wp:post-featured-image is a VOID block and
   cannot contain children, so the pattern emits wp:post-terms inside .body — a
   SIBLING of .thumb. With no positioned ancestor the pills escaped all the way
   up to `.cc section{position:relative}` and stacked in the section's top-left
   corner, one on top of the other, outside any card.
    Anchoring them to .post instead puts them over the thumbnail,
   because .thumb is the first thing in the card. Do not remove. */
.cc .post{position:relative;background:var(--cc-card);border:1px solid var(--cc-line-soft);border-radius:var(--cc-radius);overflow:hidden;
  transition:transform .4s var(--cc-ease),box-shadow .4s var(--cc-ease);display:flex;flex-direction:column}
/* WordPress's post_class() puts a bare `post` class on every Post Template <li>,
   which collides with OUR card class of the same name — so each card was drawn
   twice, nested: the <li> painted a 359px card and our inner <div class="post">
   painted a 357px one inside it, 1px off. That is the "two posts on top of each
   other". display:contents removes the <li>'s box entirely so our div becomes
   the grid item directly, which is what .cc-blog-grid expects. */
.cc .cc-blog-grid li.post{display:contents}
.cc .post:hover{transform:translateY(-5px);box-shadow:0 30px 56px -36px rgba(31,26,39,.28)}
/* 16/9 is the guide photos' own shape, as on /guides/, so nothing is cropped. The
   figure's default bottom margin (25.5px) is dropped: with no excerpt it doubled
   the gap above the title (5 October 2026). */
.cc .post .thumb{aspect-ratio:16/9;margin:0;position:relative;display:flex;align-items:center;justify-content:center}
/* The tag takes the eyebrow's size: the prototype's .6rem rendered 9.6px, under
   the 11px type floor (issue #20). Its link is text-high, so an invisible
   ::after carries the 44px target without moving the pill. On a card without a
   featured image the tag lies over the title (README: posts need one). */
.cc .post .tag{position:absolute;top:16px;left:16px;font-size:14px;letter-spacing:.16em;text-transform:uppercase;
  background:rgba(255,255,255,.85);padding:4px 8px;border-radius:14px;color:var(--cc-gray);font-weight:600}
.cc .post .tag a{position:relative}
.cc .post .tag a::after{content:"";position:absolute;inset:-14px -10px}
/* The body fills the card and "Read the guide" sits at its foot, so the links
   line up across a row whatever the titles' length (no excerpt since
   5 October 2026). flex-start keeps the link its own width. */
.cc .post .body{padding:24px 24px 28px;flex:1;display:flex;flex-direction:column;align-items:flex-start}
.cc .post h3{font-size:21px;line-height:1.18;margin-bottom:20px}
.cc .post p{font-size:17px;color:var(--cc-gray);margin-bottom:1rem}
.cc .post .read{font-size:17px;font-weight:600;color:var(--cc-accent);display:inline-flex;gap:8px;align-items:center;position:relative;margin-top:auto}
/* A 44px target without moving the card: ::after is the arrow, so ::before,
   taken out of the flex flow by position:absolute, carries it. */
.cc .post .read::before{content:"";position:absolute;inset:-11px -8px}
/* `justify-content`, not `text-align` — the prototype's `.blog-foot` is a plain
   div holding an inline-block <a>, so `text-align:center` centered it. Here the
   element IS the wp:buttons wrapper, and core gives `.wp-block-buttons`
   `display:flex`, on which text-align is inert. The button sat hard left with
   the CSS looking correct. Same fix as `.cc-about-cta .wp-block-buttons`.
   Since 10 October 2026 the steps section uses it too, for its link to the
   app guide: a button under a card grid gets one treatment on the page. */
.cc .cc-blog-foot{justify-content:center;margin-top:40px}
/* ── Saluxe band ── */
.cc .saluxe{background:linear-gradient(165deg,var(--cc-amethyst-mid) 0%, var(--cc-amethyst-deep) 100%);color:var(--cc-on-dark-muted);overflow:hidden}
.cc .saluxe::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(50% 70% at 84% 30%, rgba(203,184,239,.26),transparent 60%),
             radial-gradient(40% 60% at 10% 90%, rgba(75,58,115,.14),transparent 60%)}
.cc .saluxe-grid{position:relative;z-index:1;display:grid;grid-template-columns:1.1fr .9fr;gap:clamp(32px,5vw,72px);align-items:center}
.cc .saluxe .eyebrow{color:var(--cc-accent-on-dark)}
.cc .saluxe h2{color:var(--cc-on-dark-text);margin:1rem 0 12px}
.cc .saluxe h2 em{color:var(--cc-accent-on-dark)}
.cc .saluxe p{color:var(--cc-on-dark-muted);max-width:48ch}
/* `.cc a` resets links to plain text; the Darija link in the band's copy has to
   read as one (5 October 2026). */
.cc .saluxe p a{color:var(--cc-on-dark-text);text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px}
.cc .saluxe p a:hover{color:var(--cc-accent-on-dark)}
.cc .saluxe-cta{display:flex;gap:12px;flex-wrap:wrap;margin-top:32px}
.cc .saluxe-object{position:relative;display:flex;justify-content:center;align-items:center}
.cc .saluxe-object::before{content:"";position:absolute;top:42%;left:50%;transform:translate(-50%,-50%);
  width:78%;height:62%;border-radius:50%;z-index:0;
  background:radial-gradient(closest-side, rgba(203,184,239,.5), rgba(203,184,239,.2) 55%, transparent 76%);
  filter:blur(30px)}
.cc .saluxe-object img{position:relative;z-index:1;height:520px;width:auto;
  filter:drop-shadow(0 30px 40px rgba(28,20,38,.55))}
/* ── Newsletter ── */
.cc .news{background:var(--cc-sage-soft)}
.cc .news-inner{max-width:640px;margin:0 auto;text-align:center}
.cc .news h2{margin:1rem 0}
.cc .news form{display:flex;gap:12px;max-width:480px;margin:32px auto 0;flex-wrap:wrap;justify-content:center}
/* Inputs are 1rem, not the prototype's .95rem: under 16px iOS Safari zooms the
   page when a field is focused (design-system.md, minimum type; issue #20). */
.cc .news input{flex:1;min-width:230px;padding:16px 20px;border-radius:14px;border:1px solid var(--cc-control-border);
  background:var(--cc-card);font-family:var(--cc-sans);font-size:17px;color:var(--cc-ink)}
/* Blocksy's later input[type]:focus rules otherwise turn the white field
   transparent and change its text color. Keep both colors on the component
   focus selectors (here and in Contact), which outrank the parent theme. */
.cc .news input:focus{outline:none;border-color:var(--cc-accent);background:var(--cc-card);color:var(--cc-ink)}
.cc .cc-news-small{display:block;margin-top:1rem;color:var(--cc-gray);font-size:14px}
.cc .formnote{font-size:14px;color:var(--cc-accent);margin-top:1rem;min-height:1.2em;font-weight:600}
/* Until it has a message, the newsletter's status line takes no room: its
   reserved line and margins left 53px between the form and the small print.
   It stays in the page (not display:none) so screen readers still announce
   what is written into it (5 October 2026). */
.cc .news .formnote:empty,
.cc #contact .formnote:empty{min-height:0;margin:0}

/* The contact forms' result (both pages carry #contactNote) is a panel under the
   button, not a footnote: on 6 October 2026 the 14px line below the privacy text
   was missed on a phone, and the script now also scrolls it into view
   (crystal-cleanse.js). The panel fills with accent-soft, the same 14px
   corners as the fields and a 1px accent border; the icon is a mask, so it
   takes its colour from the token like the text does. Success and failure
   differ by icon and wording as well as colour. Ink on accent-soft measures
   12.56:1 and the accent icon 7.21:1 on it; the border is 8.78:1 on surface.
   margin is set in full because Blocksy gives a paragraph 1.5em below it,
   which measured 26px between the panel and the privacy line (6 October 2026)
   against the 16px above it. The newsletter's .formnote is deliberately not touched.
   Empty, it collapses without display:none, so the live region still announces
   what is written into it (as for the newsletter above). */
.cc #contactNote{display:flex;gap:12px;align-items:flex-start;margin:16px 0 0;padding:16px 20px;
  border:1px solid var(--cc-accent);border-radius:14px;background:var(--cc-accent-soft);
  color:var(--cc-ink);font-size:17px;font-weight:600;line-height:1.5;min-height:0}
.cc #contactNote::before{content:"";flex:none;width:24px;height:24px;margin-top:1px;
  background-color:var(--cc-accent);
  -webkit-mask:url("data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22%23000%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Ccircle%20cx=%2212%22%20cy=%2212%22%20r=%2210%22/%3E%3Cpath%20d=%22m9%2012%202%202%204-4%22/%3E%3C/svg%3E") center/contain no-repeat;
  mask:url("data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22%23000%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Ccircle%20cx=%2212%22%20cy=%2212%22%20r=%2210%22/%3E%3Cpath%20d=%22m9%2012%202%202%204-4%22/%3E%3C/svg%3E") center/contain no-repeat}
.cc #contactNote.is-error{border-color:var(--cc-error);background:var(--cc-error-soft)}
.cc #contactNote.is-error::before{background-color:var(--cc-error);
  -webkit-mask-image:url("data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22%23000%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Ccircle%20cx=%2212%22%20cy=%2212%22%20r=%2210%22/%3E%3Cline%20x1=%2212%22%20x2=%2212%22%20y1=%228%22%20y2=%2212%22/%3E%3Cline%20x1=%2212%22%20x2=%2212.01%22%20y1=%2216%22%20y2=%2216%22/%3E%3C/svg%3E");
  mask-image:url("data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22%23000%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Ccircle%20cx=%2212%22%20cy=%2212%22%20r=%2210%22/%3E%3Cline%20x1=%2212%22%20x2=%2212%22%20y1=%228%22%20y2=%2212%22/%3E%3Cline%20x1=%2212%22%20x2=%2212.01%22%20y1=%2216%22%20y2=%2216%22/%3E%3C/svg%3E")}
.cc #contactNote:empty{margin:0;padding:0;border:0;background:none}
.cc #contactNote:empty::before{display:none}
/* ── Contact ── */
.cc .contact-grid{display:grid;grid-template-columns:.85fr 1.15fr;gap:clamp(32px,5vw,72px);align-items:start}
/* The address stands in a paragraph of its own, so it is a standalone link and
   takes the 44px floor (issue #20). Inline padding leaves the line box alone. */
.cc .contact-grid p > a[href^="mailto:"]:only-child{padding-block:11px}
/* `.cc a` resets links to plain text, so the address read as gray text; it is
   underlined in the accent like the band's other links (5 October 2026). */
.cc #contact .muted a{color:var(--cc-accent);text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px}
.cc .contact-form{display:grid;gap:16px}
.cc .contact-form input,
.cc .contact-form textarea{width:100%;padding:16px 20px;border-radius:14px;border:1px solid var(--cc-control-border);
  background:var(--cc-card);font-family:var(--cc-sans);font-size:17px;color:var(--cc-ink);resize:vertical}
.cc .contact-form input:focus,
.cc .contact-form textarea:focus{outline:none;border-color:var(--cc-accent);background:var(--cc-card);color:var(--cc-ink)}
.cc .contact-form .row{display:grid;grid-template-columns:1fr 1fr;gap:16px}
/* ── About page ── */
/* Only used by patterns/about-page.php. Built on the same tokens as everything
   else — no parallel palette, no second radius scale.

   Ported from a standalone mockup (about.html) whose values were sampled by eye
   from the live site and were close but not identical. Corrected on the way in:
      6px card / 4px button radii -> --cc-radius / the .btn control radius
      #E3E5DF card border         -> --cc-line-soft
     120px fixed section padding -> .cc-section's clamp(72px,11vw,144px)
     clamp(38px,6vw,72px) h1     -> the site h1, whose 6.2vw slope is measured
                                    (decision 8; 6.4vw overflows at 1088px)
   The mockup also declared its own --sage and never used it. */

/* VERTICAL RHYTHM IS ASYMMETRIC ON PURPOSE — do not "tidy" it to uniform.
   The landing page is a stack of self-contained bands, so .cc-section's equal
   padding top and bottom is right there. This page is one continuous read:
   hero flows into the story, the story into the signed note. The mockup zeroes
   padding-top on the sections that continue a thought, and only the CTA — which
   IS a band — gets full padding on both sides.

   Ported uniform by mistake first time, which put 280px between the hero and
   the story where the design has 76. Ratios kept from the mockup (76/120 and
   96/120) rather than its fixed pixels, so this still tracks the site's clamp. */
.cc .cc-about-hero{padding-bottom:clamp(48px,7vw,88px)}
.cc .cc-about-story{padding-top:0;padding-bottom:clamp(56px,9vw,112px)}
.cc .cc-about-note-section{padding-top:0}

/* The hero headline is long — two full clauses — and .cc-center-head's 680px is
   sized for the landing page's short section heads. At 680 it broke to three
   lines.

   Widening alone was not enough: text-wrap:balance then chose "…for a living.
   So" / "we built the app we were missing.", which splits the italic accent and
   orphans "So" onto the roman line. Decision 2 is precisely about the accent
   landing whole, so the break is forced at the clause boundary instead — with
   the SAME .ln device the landing page's hero already uses, not a <br>.

   .ln is display:block, so each half is its own line at every width; inside a
   half, normal wrapping still applies on narrow screens. */
.cc .cc-about-hero .cc-center-head{max-width:none;
  /* .cc-center-head carries margin-bottom:clamp(32px,6vw,72px) for the landing
     page's section heads, which sit directly above their content. Here the
     section's own padding-bottom does that job, so inheriting both stacked ~67px
     of dead space under the hero — 147px to the first paragraph where the design
     has 76. Reused the class for its centering, not its spacing. */
  margin-bottom:0}
.cc .cc-about-hero h1{max-width:none}
.cc .cc-about-hero h1 .ln{display:block}
/* The About hero uses the shared lead size from issue #20. Keep the 1.7
   reading treatment and 32px headline offset. Balanced wrapping: the second
   text's lead left "it." alone on its third line at desktop widths (Henrik,
   4 October 2026); balance evens the centered lines instead. */
.cc .cc-about-hero .lead{max-width:560px;line-height:1.7;margin-top:32px;text-wrap:balance}

/* The measure is the whole point of this page: four long paragraphs and nothing
   else. 68ch inside a 680px column. Widen it and the page reads as a wall. */
.cc .cc-about-prose{max-width:680px;margin:0 auto}
.cc .cc-about-prose p{font-size:17px;line-height:1.8;margin:0 0 16px;max-width:68ch;color:var(--cc-gray)}
.cc .cc-about-prose p:last-child{margin-bottom:0}
/* Inline emphasis stays gray here — the violet italic is reserved for the one
   headline accent, so it keeps meaning something (decision 3). */
.cc .cc-about-prose em{font-style:italic;color:var(--cc-gray)}
/* .cc a is color:inherit, so the story's links were invisible until this rule.
   Same treatment as the Darija page: links inside sentences keep the line box
   and use an underline as the touch affordance. Accent on surface 8.78:1. */
.cc .cc-about-prose a{color:var(--cc-accent);text-decoration:underline;
  text-decoration-thickness:1px;text-underline-offset:3px}
.cc .cc-about-prose a:hover{color:var(--cc-ink)}

/* Single column is the DEFAULT and two-column is the enhancement, not the other
   way round: the card is correct with no large photo, and becomes a two-up
   when an Image block with className cc-about-photo is added. Written with
   :has() so if :has() were unsupported the page still degrades to the safe
   single column. Scoped to .cc-about-photo since the small round signature
   photo (.cc-about-avatar, below) must not trigger the two-up.
   680px, the story column's width, so the card's edges line up with the
   paragraphs above it: at 880px a one-sentence note left the right side empty
   (Henrik, 4 October 2026). A large photo would need the card wider again. */
.cc .cc-about-note{max-width:680px;margin:0 auto;display:grid;grid-template-columns:1fr;
  align-items:center;background:var(--cc-card);border:1px solid var(--cc-line-soft);
  border-radius:var(--cc-radius);overflow:hidden}
.cc .cc-about-note:has(.cc-about-photo){grid-template-columns:40% 60%}
.cc .cc-about-note .cc-about-photo img{width:100%;height:100%;object-fit:cover;aspect-ratio:4/5;display:block}
.cc .cc-about-note-body{padding:clamp(32px,4vw,48px) clamp(24px,4vw,48px)}
.cc .cc-about-note blockquote{margin:0;font-family:var(--cc-serif);font-size:21px;
  line-height:1.6;font-style:normal;color:var(--cc-ink)}
.cc .cc-about-sig{margin-top:24px;font-size:14px;line-height:1.6;color:var(--cc-gray)}
.cc .cc-about-sig strong{color:var(--cc-ink);font-weight:600}
.cc .cc-about-sig a{color:var(--cc-accent)}
.cc .cc-about-sig a:hover{text-decoration:underline}
/* The signature row: Henrik's round photo beside his name, like a byline
   (Henrik, 4 October 2026). 64px on the 4px grid; the source is at least
   400px square, so it stays sharp at 2x. The figure's default block margin is
   removed so the photo centers on the two signature lines. */
.cc .cc-about-signer{display:flex;align-items:center;gap:16px;margin-top:24px}
.cc .cc-about-signer .cc-about-sig{margin-top:0}
.cc .cc-about-avatar{flex:none;width:64px;margin:0}
.cc .cc-about-avatar img{display:block;width:64px;height:64px;border-radius:50%;object-fit:cover}

/* Same accent-to-session ramp as the Saluxe band, centered rather than
   two-column. The eyebrow uses accentOnDark: calculated 5.41:1 even at the
   plum stop (decision 6, issue #20). */
.cc .cc-about-cta{background:linear-gradient(165deg,var(--cc-amethyst-mid) 0%, var(--cc-amethyst-deep) 100%);
  color:var(--cc-on-dark-muted);text-align:center;overflow:hidden}
.cc .cc-about-cta .eyebrow{color:var(--cc-accent-on-dark)}
.cc .cc-about-cta h2{color:var(--cc-on-dark-text);margin:1rem 0 0}
.cc .cc-about-cta p{color:var(--cc-on-dark-muted);max-width:48ch;margin:24px auto 36px}
.cc .cc-about-cta .wp-block-buttons{justify-content:center}

/* ── Darija page ── */
/* Flat palette-2 grounds: gray on sage/surface is 8.50/9.54:1 (as recorded
   above); ink is 13.62/15.29:1 and accent is 7.82/8.78:1, calculated from the
   current tokens with WCAG relative luminance. All clear 4.5:1. */
.cc .cc-darija-hero{position:relative;overflow:hidden;
  padding-top:clamp(48px,7vw,88px);padding-bottom:clamp(56px,9vw,120px)}
/* The absolute portrait spans the grid plus the section padding. Measured on
   3 October 2026 in a 1440×900 frame of the live site: 48vw makes the portrait
   677×899, the approved 3:4 of design 4b, and keeps the hero within one screen;
   56vw made it 677×1014 and pushed the name low. At 1180px it is about 553×755.
   The 760px cap brings it near square at 1920px, like the home hero. */
.cc .cc-darija-grid{display:grid;grid-template-columns:1fr 1fr;
  gap:clamp(32px,5vw,72px);align-items:center;min-height:clamp(520px,48vw,760px)}
/* Blocksy's flow-group children carry bottom margins even in CSS grids.
   Reset them here so the grid gap alone sets the spacing, as on About. */
.cc .cc-darija-grid > *,
.cc .cc-darija-cards > *,
.cc .cc-darija-photos > *{margin-block:0}
.cc .cc-darija-text{min-width:0}
.cc .cc-darija-text h1{margin:0}
.cc .cc-darija-role{font-size:21px;color:var(--cc-gray);margin:16px 0 0}
.cc .cc-darija-text .lead{margin:40px 0 0}
.cc .cc-photo-slot{position:relative;overflow:hidden;background:var(--cc-sage)}
.cc .cc-photo-slot > figure{position:absolute;inset:0;margin:0;width:100%;height:100%}
.cc .cc-photo-slot > figure > img{display:block;width:100%;height:100%;object-fit:cover}
.cc .cc-darija-portrait{position:absolute;top:0;bottom:0;right:0;
  left:calc(50% + clamp(16px,2.5vw,36px));border-radius:0;box-shadow:none}
/* Faces sit in the upper part of a portrait. Rechecked with her live portrait
   (3:4 source) on 6 October 2026: at 1440px the slot is 677×899, an exact 3:4,
   so nothing crops; at 1918px it is 916×968 and at 820px 820×720, and her face
   stays well inside the frame at 50% 30%. */
.cc .cc-darija-portrait > figure > img{object-position:50% 30%}
/* This is one continuous page. The preceding section's bottom padding supplies
   each seam's gap; adding another section's top padding would double it. */
.cc .cc-darija-roles,
.cc .cc-darija-path{padding-top:0}
.cc .cc-darija-roles h2,
.cc .cc-darija-prose h2{margin:0 0 24px}
.cc .cc-darija-cards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:24px;align-items:stretch}
.cc .cc-darija-card{background:var(--cc-sage);border-radius:var(--cc-radius);padding:28px;border:0;box-shadow:none}
.cc .cc-darija-card p{font-size:17px;line-height:1.6;color:var(--cc-gray);margin:0}
.cc .cc-darija-card strong{font-weight:600;color:var(--cc-ink)}
/* Inline emphasis keeps the prose color; the site's heading-accent rule would
   otherwise turn the publication titles plum, including inside hovered links. */
.cc .cc-darija-card em{color:inherit}
.cc .cc-darija-prose{max-width:600px;margin:0 auto}
.cc .cc-darija-prose p{font-size:17px;line-height:1.6;color:var(--cc-gray);margin:0 0 16px}
.cc .cc-darija-prose p:last-child{margin-bottom:0}
.cc .cc-darija-photos{max-width:960px;margin:48px auto 0;display:grid;grid-template-columns:1fr 1fr;gap:24px}
.cc .cc-darija-photo{aspect-ratio:3/2;border-radius:var(--cc-radius-lg)}
/* These links sit inside sentences: keep the normal line box and use an
   underline for the touch affordance (Henrik, 3 October 2026). */
.cc .cc-darija-hero a,
.cc .cc-darija-roles a,
.cc .cc-darija-path a{color:var(--cc-accent);text-decoration:underline;
  text-decoration-thickness:1px;text-underline-offset:3px}
.cc .cc-darija-hero a:hover,
.cc .cc-darija-roles a:hover,
.cc .cc-darija-path a:hover{color:var(--cc-ink)}

/* ── Contact page ── */
/* Only used by patterns/contact-page.php. Deliberately thin: .cc-center-head,
   .contact-grid, .contact-form and .formnote already exist for the landing
   page's #contact section, and the standalone page reuses all four. What is
   below is only what the page adds on top of them. */

/* Same reason as .cc-about-hero: .cc-center-head carries
   margin-bottom:clamp(32px,6vw,72px) for the landing page's section heads,
   which sit directly above their content. Here the next section's padding does
   that job, so inheriting both stacks two gaps. Reused for its centering. */
.cc .cc-contact-hero .cc-center-head{margin-bottom:0}
/* The head and the grid read as one unit, so the body opens flush against the
   hero rather than starting a second band. */
.cc .cc-contact-body{padding-top:0}

/* An h2, not an h3, because the page outline must not jump h1 -> h3. Sized as
   an h3 because the real h2 clamp tops out at 3.25rem — a band heading, three
   times too large sitting in a 0.85fr column. */
.cc .cc-contact-subhead{font-size:24px}

.cc .cc-contact-list{list-style:none;display:flex;flex-direction:column;
  gap:16px;margin-top:24px;padding-left:0}
.cc .cc-contact-list li{display:flex;gap:16px;align-items:center;min-height:32px;
  color:var(--cc-gray);font-size:17px;line-height:1.6}
/* The icons are background images on ::before, not <svg> in the markup, and the
   reason is translation rather than taste: inline SVG would force this list
   into a Custom HTML block, which hands Polylang one opaque blob instead of
   three translatable list items. Same mechanism as .feat on the landing page.

   Badge geometry is copied from .feat verbatim — 32px, 14px radius, the same
   6%-ink wash — so the two lists read as one family. The layout differs on
   purpose: .feat items are a bold title over a paragraph and top-align, while
   these are single sentences, so they center against the badge instead.

   stroke is #1F1A27 and not currentColor: a background image cannot inherit
   the text color. If --cc-ink ever changes, these three URIs and .feat's four
   do not follow it — they are baked. sources/icons/ holds the editable
   originals, and editing one there changes nothing until it is re-encoded.

   Order-coupled by :nth-child, exactly as .feat is. Reorder the list in
   patterns/contact-page.php and these must be reordered with it — nothing will
   error if they are not, the icons will simply be wrong. */
.cc .cc-contact-list li::before{content:"";flex:none;width:32px;height:32px;
  border-radius:14px;background-color:rgba(31,26,39,.06);
  background-repeat:no-repeat;background-position:center;background-size:24px 24px}
/* 1. Choosing a crystal / how to cleanse one — sources/icons/contact_crystals.svg */
.cc .cc-contact-list li:nth-child(1)::before{background-image:url("data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22%231F1A27%22%20stroke-width=%221.5%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Cpath%20d=%22M6%203h12l4%206-10%2013L2%209Z%22/%3E%3Cpath%20d=%22M11%203%208%209l4%2013%204-13-3-6%22/%3E%3Cpath%20d=%22M2%209h20%22/%3E%3C/svg%3E")}
/* 2. Feedback, or something not working — sources/icons/contact_feedback.svg */
.cc .cc-contact-list li:nth-child(2)::before{background-image:url("data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22%231F1A27%22%20stroke-width=%221.5%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Cpath%20d=%22M7.9%2020A9%209%200%201%200%204%2016.1L2%2022Z%22/%3E%3C/svg%3E")}
/* 3. Press, partnerships and collaborations — sources/icons/contact_press.svg */
.cc .cc-contact-list li:nth-child(3)::before{background-image:url("data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22%231F1A27%22%20stroke-width=%221.5%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Cpath%20d=%22M16%2021v-2a4%204%200%200%200-4-4H6a4%204%200%200%200-4%204v2%22/%3E%3Ccircle%20cx=%229%22%20cy=%227%22%20r=%224%22/%3E%3Cpath%20d=%22M22%2021v-2a4%204%200%200%200-3-3.87%22/%3E%3Cpath%20d=%22M16%203.13a4%204%200%200%201%200%207.75%22/%3E%3C/svg%3E")}

.cc .cc-contact-direct{margin-top:36px;padding-top:32px;border-top:1px solid var(--cc-line)}
/* .cc a is color:inherit, so links are ink unless a rule opts them in. These
   two are the only links on the page and both are the point of it. */
.cc .cc-contact-direct a{color:var(--cc-accent);font-size:17px;font-weight:500}
.cc .cc-contact-direct a:hover{text-decoration:underline}
.cc .cc-contact-note{margin-top:.5rem;font-size:14px;color:var(--cc-gray);line-height:1.6}
/* Micro-copy on the page surface uses muted: calculated 5.84:1 on surface
   under palette 2 (issue #20). */
.cc .cc-contact-saluxe{margin-top:24px;font-size:14px;color:var(--cc-muted);line-height:1.6}
/* Privacy keeps gray, as decision 7 requires for quiet text. Calculated
   9.54:1 on surface under palette 2. The line remains a separate paragraph
   so it stays translatable. */
.cc .cc-contact-privacy{font-size:14px;color:var(--cc-gray);line-height:1.6;margin-top:16px}
.cc .cc-contact-privacy a{color:var(--cc-accent)}
.cc .cc-contact-privacy a:hover{text-decoration:underline}

/* ── Reveal animation ──
   Shorter and lighter since 10 October 2026 (Henrik, decision 19): .8s and
   22px left a block blank for most of a second after it scrolled in. The hero
   never animates. It is the first screen, and fading it in made the page
   start empty; its two .reveal columns stay in page 17's markup. */
.cc .reveal{opacity:0;transform:translateY(12px);transition:opacity .5s var(--cc-ease),transform .5s var(--cc-ease)}
.cc .reveal.in,
.cc .cc-hero .reveal{opacity:1;transform:none}
.cc .cc-hero .reveal{transition:none}
/* ── Responsive ── */
@media(max-width:980px){
.cc .cc-hero{padding-bottom:0}
.cc .hero-grid,
.cc .ritual-grid,
.cc .saluxe-grid,
.cc .contact-grid{grid-template-columns:1fr}
/* Text first keeps Open the App in the first phone screen: the prototype put
   its bottom at 614px at 390×844; photo first put it at 858px. */
.cc .hero-grid{min-height:0;gap:32px}
/* The negative inline margin cancels the centered content width and section
   gutter so the photo meets both viewport edges and the next section. It is
   4:5, the photo's own shape, because it sits below the buttons: its height no
   longer pushes Open the App down. The 720px cap stops tablets giving it a
   whole screen (768px wide would be 960px tall); there it crops to near square. */
.cc .hero-photo{position:relative;left:auto;top:auto;bottom:auto;right:auto;margin-inline:calc(50% - 50vw);width:100vw;max-width:none}
.cc .hero-photo .frame{height:auto;aspect-ratio:4/5;max-height:720px}
/* Photo first is safe here: unlike the home hero, Darija has no button that
   must remain in the first screen. Zero top padding starts it under the header. */
.cc .cc-darija-hero{padding-top:0}
.cc .cc-darija-grid{grid-template-columns:1fr;min-height:0;gap:32px}
.cc .cc-darija-portrait{position:relative;top:auto;bottom:auto;right:auto;left:auto;
  order:-1;margin-inline:calc(50% - 50vw);width:100vw;max-width:none;aspect-ratio:3/4;max-height:720px}
.cc .crystal-grid{grid-template-columns:repeat(3,1fr)}
.cc .saluxe-object img{height:440px}
}
@media(max-width:760px){
/* On phones the button wraps under the field; full width, it lines up with it. */
.cc .news form .btn{flex:1 1 100%}
.cc .cc-hero .eyebrow{font-size:14px}
.cc .cc-about-note{grid-template-columns:1fr}
.cc .cc-about-note .cc-about-photo img{aspect-ratio:16/10}
.cc .cc-about-prose p{font-size:17px;margin-bottom:16px}
.cc .cc-darija-text .lead{margin-top:32px}
.cc .cc-darija-cards{grid-template-columns:1fr}
.cc .cc-darija-card{padding:20px}
.cc .cc-darija-prose h2{margin-bottom:16px}
/* Gutenberg's constrained section centers children with important margins;
   the extra path class also beats style.css's direct-child width:100% rule. */
.cc .cc-darija-path .cc-darija-photos{grid-template-columns:1fr;gap:12px;margin-top:32px;
  margin-inline:calc(50% - 50vw) !important;width:100vw;max-width:none}
.cc .cc-darija-photo{border-radius:0}
.cc h1{font-size:clamp(2rem,11.2vw,2.9rem)}
.cc .steps{grid-template-columns:1fr}
.cc .crystal-grid{grid-template-columns:repeat(2,1fr)}
.cc .contact-form .row{grid-template-columns:1fr}
}
