/* WordPress-specific additions. The visual system remains split across the four migrated CSS files. */

.wp-caption { max-width: 100%; }.alignleft { float: left; margin: 0 1.5rem 1rem 0; }.alignright { float: right; margin: 0 0 1rem 1.5rem; }.aligncenter { display: block; margin-left: auto; margin-right: auto; }.screen-reader-text { clip: rect(1px,1px,1px,1px); clip-path: inset(50%); height: 1px; overflow: hidden; position: absolute !important; width: 1px; word-wrap: normal !important; }.screen-reader-text:focus { background: var(--white); clip: auto !important; clip-path: none; color: var(--charcoal); display: block; font-size: 1rem; height: auto; left: 5px; padding: 15px 23px 14px; top: 5px; width: auto; z-index: 100000; }.site-main-content { min-height: 45vh; }.wp-block-image img { height: auto; }.entry-content > * { max-width: 780px; margin-left: auto; margin-right: auto; }.entry-content > .alignwide { max-width: 1200px; }.entry-content > .alignfull { max-width: none; }/* ---------- Calendar page (page-templates/template-calendar.php) ---------- */

/* The template, not the filter, owns this layout now. Every rule below is about
   one page and is scoped to .cal-page, which the body-class map adds for that
   template only, so none of it can reach the twenty-odd other pages the theme
   renders.

   Two of these are repairs rather than styling, and both were visible on the live
   page before they were written.

   The first is the centring. .entry-content > * above centres its children with
   margin-left and margin-right of auto, and the two rules for the lines the
   booking hand-off adds set margin with the shorthand:

       .entry-content .bk-scheduler-tz { margin: 0 0 14px; ... }(0, 2, 0)
       .entry-content .bk-chosen-service { margin: 0 0 18px; ... }(0, 2, 0)

   The shorthand outranks the (0, 1, 0) rule and resets the side margins to zero on
   its way to setting the bottom one. So those two lines were the only children of
   .entry-content that finished up hard against the left, on a page whose title
   and lead were both centred. Measured on the live site before this: their boxes
   sat at left=168 inside a container running 168 to 1268, so the text inside
   centred at 558 where the container centre is 718. The lead, which nothing
   overrides, sat exactly on 718.

   It was never visible as a fault because both lines are short and the page looked
   plausible. It was visible as a comparison: one line centred, two beside it
   not.

   The second is the fixed header. .site-header is position: fixed and --header-h
   is 80px, so whatever comes first has to clear it. Every static page clears it by
   accident, opening with a hero carrying clamp(76px, 11vw, 132px) of top padding.
   A WordPress page does not: page.php opens with .section, whose top padding is
   clamp(32px, 4.2vw, 48px), which is less than the header standing over it.
   Measured: the header ended at 80px and the h1 began at 77px, so the top 3px of
   the title sat behind the bar.

   Written as the header height plus a gap rather than as one larger number, because
   --header-h changes at the widths where the header collapses and a fixed pixel
   value would quietly stop clearing it at exactly the widths where it is
   shortest. scroll-margin-top is the other half, because an anchor link would
   otherwise land the title under the header. */

.cal-page { padding-top: calc(var(--header-h) + clamp(40px, 5vw, 64px)); scroll-margin-top: var(--header-h); }/* The heading, the lead and both added lines share one centre line. Scoped to the
   section rather than to entry-content alone, because page.php prints section-head
   as a sibling of it and the heading cannot be reached from inside. */
.cal-page .section-head, .cal-page .entry-content { text-align: center; }/* 520px on the three text lines. .lead defaults to 52ch on the container measure, which is a ragged edge in the middle of a page whose whole job is one centred
   choice, and the three lines would otherwise disagree about where the centre is.
   The lead sits between the two added lines by size and carries no emphasis, which
   is the right reading: it is a sentence about the page, the two below it are the
   facts about their booking. */
.cal-page .entry-content > .lead { max-width: 520px; margin-left: auto; margin-right: auto; margin-bottom: 22px; }/* The side margins for the two added lines, at (0, 3, 1).

   They are fighting a shorthand. Further down this same file:

       .entry-content .entry-content .bk-scheduler-tz { margin: 0 0 14px; ... }sits at (0, 2, 0) and so comes later in the cascade, and the shorthand resets
   margin-left and margin-right to zero on its way to setting the bottom one. That is
   the same shorthand that cancels the centring from .entry-content > *, and it
   cancelled it a second time after the first was fixed. Naming the element and
   adding .entry-content wins on specificity rather than on position in the file, which is the only durable way to win - theme-wp.css loads before breakpoints.css, so a tie at equal specificity would lose.

   No max-width here, deliberately. An earlier version clamped both lines to 520px to
   match .lead, and that is what forced the time zone line onto two lines: it is
   around 560px of text at its own size, so the clamp broke a sentence that fits the
   site's reading measure. Both lines now take the 780px that .entry-content > *
   already gives every other child, which is what "one line, centred" needs.

   text-align is not set here either, and does not need to be. The justified reading
   measure further down this file is !important, which cannot be beaten by any
   specificity - an important declaration only loses to another important one - so
   the two classes were excluded from that rule outright with :not(), in the same way
   .lead already is. Nothing declares text-align on them now, so they inherit the
   centre from .cal-page .entry-content above, and they inherit no hyphenation
   either, which is right for a label. */
.site-main-content .cal-page .entry-content p.bk-scheduler-tz, .site-main-content .cal-page .entry-content p.bk-chosen-service { margin-left: auto; margin-right: auto; }/* Both bold, and a step apart rather than equal. The service is the fact the
   visitor came to act on; the time zone is the condition they read it under. Set
   identically they compete, and the page ends with two lines of the same weight
   saying different kinds of thing.

   The time zone also comes off the muted colour. Muted grey is right for a caption
   nobody can act on, and a bold caption at that weight and contrast reads as an
   error rather than as quiet. #2F2A22 sits between the muted and the ink and
   matches the existing .bk-scheduler-tz strong rule above rather than inventing a
   shade. */
.site-main-content .cal-page .entry-content p.bk-scheduler-tz, .site-main-content .cal-page .entry-content p.bk-chosen-service { font-weight: 600; }.site-main-content .cal-page .entry-content p.bk-chosen-service { font-size: 1.22rem; color: var(--ink); }.site-main-content .cal-page .entry-content p.bk-scheduler-tz { font-size: 1.02rem; color: #2F2A22; }/* Gutenberg writes ordinary links into post bodies, and those links should be
   accented and underlined. But this selector also matched the theme's own
   buttons, because a .btn inside a post is an <a class="btn btn-dark"> and
   single.php puts the booking button inside .entry-content. That made
   .entry-content a, specificity (0, 1, 1), override .btn at (0, 1, 0), so the
   button rendered with gold underlined text on its own dark fill: teal on
   near-black, and the underline the button is not supposed to have.
   Excluding the button classes hands those links back to .btn. */
.entry-content a:not(.btn):not(.cinematic-btn):not(.wp-block-button__link) { color: var(--gold); text-decoration: underline; }/* ---------- Cal.com inline embed ----------
   Cal.com injects its own stylesheet into whichever page the embed lands on, and
   that stylesheet fixes the inline embed at 780px wide and lets its observer set
   the height. On /calendar/ the page is a plain WordPress page inside
   container-narrow, which is 1088px wide, so 308px of it went unused, and the
   measured height of 530px cut the last time slots off the bottom of the card.

   Measured on the live page before and after, and re-read two and a half seconds
   later so Cal's own resize observer had run and settled:

       container width   780px  ->  1088px
       embed width       780px  ->  1088px
       embed height      530px  ->   720px

   The height is a floor, not a cap. Cal still grows the frame to fit its own
   content, so this cannot clip a longer day; it only stops a short one being
   cut short. The width has to be !important because Cal declares its own cap
   that way.

   This lives here rather than in booking.css because /calendar/ is a plain page
   rendered by page.php, and booking.css is only enqueued for the booking
   template, so rules there would not reach it.

   The heading names Cal.com because that is the older name, and the same rules
   cover Calendly. Calendly declares its own height inline on the widget, so the
   floor is stated as a min-height and nothing is capped. Cal's selectors are kept
   because a site that still has the Cal.com plugin may still carry the old
   shortcode in a page { max-width: none !important; width: 100% !important; }.entry-content .cal-inline { min-height: 720px !important; }.entry-content .calendly-inline-widget, .entry-content .calendly-inline-widget iframe { max-width: none !important; width: 100% !important; min-height: 720px !important; }.entry-content .entry-content .bk-scheduler-tz { margin:0 0 14px; font-size:15px; color:#6b6357; }.entry-content .bk-visitor-tz strong, .entry-content .bk-scheduler-tz strong { color:#201c16; font-weight:600; }/* The service the visitor chose on the booking form, echoed above the scheduler
   so the hand-off reads as one continuous booking rather than two pages. Sits
   with the timezone lines above it and is styled as a lead, not as a heading:
   it states what is being booked, it does not introduce a section. */
.entry-content .bk-chosen-service { margin:0 0 18px; font-size:1.05rem; color:var(--ink); }
@media (max-width: 860px) {.entry-content .cal-inline { min-height: 640px !important; }.entry-content .calendly-inline-widget, .entry-content .calendly-inline-widget iframe { min-height: 640px !important; }
}.entry-content ul, .entry-content ol { padding-left: 1.35rem; list-style: initial; }.pagination { display: flex; gap: .5rem; justify-content: center; margin-top: 2rem; }.pagination .page-numbers { background: var(--white); border: 1px solid var(--line); padding: .6rem .9rem; border-radius: 999px; }.pagination .current { background: var(--gold); color: var(--white); border-color: var(--gold); }/* Theme templates and native form presentation */

/* The accent span inside a heading is deliberately not restyled here.
   Statically .em-serif only sets font-style: normal and colour: inherit, so the
   accented word keeps the heading's own face, Bricolage Grotesque, and stays
   upright. This file previously forced Georgia, italic and a lighter weight onto
   .display .em-serif, .h-section .em-serif and .h-display .em-serif. This
   stylesheet loads last { padding-bottom: 5rem; }.hero-actions, .cta-actions { display: flex; flex-wrap: wrap; gap: .75rem; align-items: center; }.btn-block { display: flex; width: 100%; justify-content: center; }.section-head.narrow { max-width: 780px; margin-inline: auto; }.service-aside { position: sticky; top: calc(var(--header-h) + 2rem); align-self: start; }.aside-card { display: grid; gap: 1rem; background: var(--white); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: clamp(1.4rem, 3vw, 2rem); box-shadow: var(--shadow-card); }.aside-card h2, .aside-card h3 { margin: 0; }.aside-card .btn { margin-top: .5rem; }@media (max-width: 1024px){.service-aside { position: static; } }.service-hero-grid, .contact-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(2rem, 6vw, 7rem); align-items: center; }.about-hero, .service-detail-hero, .contact-hero { background: var(--stone); padding-bottom: 5rem; }.service-hero-media img, .split-media img, .post-featured img { width: 100%; height: 100%; object-fit: cover; border-radius: var(--radius-lg); }/* The page-wide banner bands have no radius, on every page.

   Eight of the ten banner pages share one family: About, FAQ, poem, Contact, the Services, Packages and Resources banners, and the Blog hero, each with a
   media box at y=0 under the fixed header; Home, Services and Packages carry
   the same band as .hero-bg. Static has their corners square, and, with the
   fixed header stroking across the top edge, a rounded corner reads as a notch
   in the band.

   .about-hero-media img used to sit in the card rule above and was the one
   band that actually got the 24px rounding; the other three selectors there
   are inset cards, where a radius is the design and stays. The banner family
   is declared square here, including .hero-bg, so no member of it inherits a
   rounding from any other rule later or earlier. */
:is(.about-hero-media, .faq-hero-media, .poem-hero-media, .contact-hero-media, .services-banner-media, .packages-banner-media, .resources-banner-media, .blog-hero-media) img, .hero-bg img { border-radius: 0; }/* The bare .portrait utility that stood here was max-width:520px with
   margin-left:auto. It was dead. portrait appears in exactly two places in
   this theme, both of them as mini-cards ... portrait, and the shared CSS
   only ever styles .mini-cards.portrait, which is the media aspect ratio.
   Because theme-wp.css loads after layout.css and page-overrides.css it
   won on order and beat .mini-cards.cols-4, collapsing the Resources guide
   grid from 1088px to 520px with 112px cards, text wrapping to three lines
   and the Download buttons clipped. It also beat .res-narrow, so the eBook
   and audio grids lost their 720px limit too. Deleted rather than
   neutralised: an override would have to out-specify a rule that should not
   exist, and any future .portrait would inherit the fight. */ 
.section-head.space { margin-bottom: 2rem; }.price { color: var(--gold); font-weight: 700; margin: 1.25rem 0; }.price { font-size: 1.6rem; }.form h2 { margin-bottom: 1.25rem; }.form label { display: block; color: var(--charcoal-2); font-size: .85rem; font-weight: 600; margin-bottom: 1rem; }.form input, .form select, .form textarea { width: 100%; border: 1px solid var(--line); background: var(--ivory); color: var(--charcoal); border-radius: var(--radius-sm); padding: .8rem .9rem; font: inherit; margin-top: .35rem; }.form textarea { resize: vertical; }/* The contact form's submit button was spanning the whole column at 957px.
   It is not padding and not .btn. .contact-form is display:grid, and a grid item
   is blockified: the inline-flex on .btn computes to flex, and the default
   justify-self:stretch then makes it fill the column. Shrink-to-fit, which is
   what inline-flex was asking for, never gets a say.

   So the button is not too wide by accident of styling - it is being actively
   stretched by its parent, and no amount of trimming .btn's padding would have
   touched it. justify-self:start is what returns it to its content width, which
   is why the comparable button on the booking page, sitting in a flex row rather
   than a grid, has always measured a sensible 200px.

   This lives here rather than in page-overrides.css because that layer is
   byte-identical to the static site's and its .contact-form grid is shipped
   content, not a WordPress artefact. */
.contact-form > button[type="submit"] { justify-self: start; }.form input:focus, .form select:focus, .form textarea:focus { outline: 2px solid var(--gold-soft); border-color: var(--gold); }.form-message { padding: .75rem 1rem; border-radius: var(--radius-sm); margin-top: 1rem; }/* Form feedback takes its colour from the site palette rather than ad-hoc
   hexes. Success is the accent, the same teal the static site already uses for
   .form-success and .form-status-success. Error keeps the exact red the static
   site's .error / .field-error rules use, so a validation message is the same
   colour here as on the original. Success and error stay distinguishable: pale
   accent against a warm neutral, not two tinted panels. */
.form-message.success { background: var(--gold-soft); color: var(--gold); }.form-message.error { background: var(--ivory-2); color: #b42318; }.chat-messages { min-height: 360px; max-height: 520px; overflow-y: auto; padding: 1.5rem; background: var(--ivory); }.chat-msg { max-width: 82%; padding: .8rem 1rem; border-radius: 14px; margin-bottom: .75rem; white-space: pre-line; }.chat-msg--ai { background: var(--white); border: 1px solid var(--line); margin-right: auto; }.chat-input-field { flex: 1; min-width: 0; border: 1px solid var(--line); border-radius: 999px; padding: .8rem 1rem; background: var(--ivory); }.chat-input-field:focus { outline: 2px solid var(--gold-soft); border-color: var(--gold); }.result-card { margin: 1rem; padding: 1.5rem; border: 1px solid var(--gold); border-radius: var(--radius-md); background: var(--gold-soft); }.result-label { color: var(--gold); font-size: .75rem; text-transform: uppercase; letter-spacing: .1em; }.result-actions { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: 1rem; }.gallery-item { border: 0; padding: 0; background: var(--white); border-radius: var(--radius-md); overflow: hidden; text-align: left; cursor: pointer; }.gallery-item img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }.gallery-item span { display: block; padding: .75rem 1rem; font-weight: 600; }/* The lightbox is styled entirely by layout.css, which is the static site's own
   rule set and is not overridden here on purpose.
   A previous version carried a duplicate block, and its ".lightbox:not([hidden])"
   rule was the cause of the viewer covering the whole page on load. The markup
   has no hidden attribute, so :not([hidden]) matched every time and forced
   display: grid, beating the .lightbox { display: none }it was meant to defer
   to. The viewer is opened by adding the open class in main.js, which is what
   layout.css keys off. The duplicated rules also drifted from static, using a
   different overlay colour, padding and image width. */
/* removed: design already declares this */ 
/* removed: design already declares this */ 
.post-meta .dot::before { content: '·'; }/* Six rules were deleted from here because they restated a design class with
   different numbers rather than adapting WordPress. This file loads after the
   shared CSS, so each one silently won on order. design says max-width 720px, this said 780px */ 
.flush-top { padding-top: 0; }/* removed: design already declares this */ 
.post-author img { width: 64px; height: 64px; object-fit: cover; border-radius: 50%; }/* removed: design already declares this */ 
.comments-area { max-width: 780px; margin: 0 auto; }.legal-copy h2 { margin-top: 2.5rem; }.site-footer { position: relative; z-index: 2; }/* ---------- Primary button: the theme accent ----------
   .btn-dark was --charcoal #201C16, so the site's main call to action was a
   near-black rectangle on an off-white page. It is now the brand accent
   --gold #22544C with white text, which is what .btn-gold already was and what
   the site uses everywhere else for a primary action.

   This is written in this file rather than in the frozen design-tokens.css
   because that file is byte-identical to the static source and must stay so.
   It lands correctly anyway: this stylesheet is enqueued after design-tokens, layout and page-overrides, so at equal specificity it comes later in the
   cascade and wins.

   The focus ring is deliberately left as the theme sets it, 3px solid var(--gold) at 3px offset, on :focus-visible only. It is the
   site's keyboard focus indicator, the static stylesheet put it there on
   purpose, and it is still visible from outside the button because the offset
   draws it on the page ground rather than on the button. Removing it is one
   line: .btn:focus-visible { outline: none; }It should not be done quietly, because it is the only cue a keyboard user has for where they are. */
.btn-dark { --btn-bg: var(--gold); color: #fff; }@media (max-width: 800px){.service-hero-grid, .contact-grid { grid-template-columns: 1fr; gap: 2rem; }.form-row { grid-template-columns: 1fr; }.chat-msg { max-width: 92%; }
}
/* Removed: the legal and media page styling (and their responsive rules).

   Every one of these styled a template that no longer exists. b7df4a3 removed
   twelve unreachable page templates, and the legal and gallery/video templates
   went with them; nothing left in the theme emits a single one of these classes,
   which is what the dead CSS gate measures across all 93 sources.

   The responsive blocks that rode along on these lines were part of the same
   removed layouts and are gone for the same reason. The reduced-motion reveal
   safety net that followed them on one line is NOT removed and is still there. */
/* Reveal-state safety: if JS/GSAP fails or reduced motion is enabled, scroll-hidden content must always be visible. */@media (prefers-reduced-motion: reduce){.gs-up, .gs-fade, .gs-scale, .hero-eyebrow, .hero-headline, .hero-desc, .hero-actions a, .trust-item, .hero-stat-card, .hero-badge, .hero-figure img, .hero-glow, .section-head .eyebrow, .section-head .h-section, .section-head .lead, .section-head .em-serif, .cta-actions .btn {
    opacity: 1 !important;
    transform: none !important;
    visibility: visible !important;
  }
}/* The same guard for a visitor with JavaScript turned off, or for the case
   where the script never arrives at all, which is the same thing from the
   page's point of view: no GSAP, so nothing is ever revealed.

   The reveal state lives in layout.css, .gs-up { opacity: 0; transform:
   translateY(40px) }, and only GSAP takes it back. The reduced-motion rule
   above covers a visitor who asks for less motion, but nothing covered a
   visitor who gets no script, so every .gs-up block on the site stayed
   invisible and the pages read as empty. The hook for it was already in the
   markup: header.php prints class="no-js" on the html element and an inline
   script swaps it for "js" on the first line of the page. That swap is what
   decides this, and it is why the guard is written against .no-js: with the
   script running the class is "js" and nothing here applies, and with it not
   running the class stays "no-js" and everything on the page is visible.
   The selector list is the reduced-motion list, which is the full set of
   elements the scripts hide. */
.no-js .gs-up, .no-js .gs-fade, .no-js .gs-scale, .no-js .hero-eyebrow, .no-js .hero-headline, .no-js .hero-desc, .no-js .hero-actions a, .no-js .trust-item, .no-js .hero-stat-card, .no-js .hero-badge, .no-js .hero-figure img, .no-js .hero-glow, .no-js .section-head .eyebrow, .no-js .section-head .h-section, .no-js .section-head .lead, .no-js .section-head .em-serif, .no-js .cta-actions .btn {
  opacity: 1 !important;
  transform: none !important;
  visibility: visible !important;
}/* Logged-in admin bar must not cover the fixed header or mobile drawer. */
body.admin-bar .site-header { top: 32px; }body.admin-bar .site-header .nav-backdrop { top: 32px; }body.admin-bar .site-header .nav { top: 32px; }body.admin-bar .skip-link { top: 46px; }
@media screen and (max-width: 782px){body.admin-bar .site-header { top: 46px; }body.admin-bar .site-header .nav-backdrop { top: 46px; }body.admin-bar .site-header .nav { top: 46px; }body.admin-bar .skip-link { top: 58px; }
}/* ---------- Book schedule (free Discovery Call) ----------
   Styles for the scheduler. They live here rather than in page-overrides.css
   because that file is byte-identical to the static site's, and these classes are used by exactly one WordPress template and no static
   page. Adding them there would make the two copies differ for no gain.

   The .bk-* classes are shared names with book-a-call.php, not duplicates: the
   two pages finish on the same confirmation, so they carry the same marks. The
   .cal-hero and .cal-section bands are not restated here at all - they already
   exist in page-overrides.css and are grouped there with the other page bands. */
.bk-embed { border: 1px solid var(--line); border-radius: var(--radius-lg); overflow: hidden; background: var(--white); }.bk-embed-placeholder { padding: 56px 24px; text-align: center; }.bk-embed-placeholder i { font-size: 2.6rem; color: var(--line); display: block; margin-bottom: 14px; }.bk-embed-placeholder h3 { margin-bottom: 8px; }.bk-embed-placeholder p { color: var(--muted); max-width: 420px; margin: 0 auto 20px; }.bk-embed-placeholder code { background: var(--ivory); padding: 1px 5px; border-radius: 4px; font-size: 0.85em; }@media (max-width: 600px) {
}/* ---------- Justified body copy: removed, and why it does not come back ----------

   Whole block deleted: the (0, 3, 1) measure that forced justify on body copy
   above 861px, and with it the four counter-rules that existed only to fight
   it: the calendar labels' centre, the philosophy detail's left, the
   short-label reset and the card-grid exclusion, all at (0, 4, 1) with their
   own !important. Each of those was a patch on the last stretch-gap
   screenshot; the stretch-gaps were the measure, so they go with it.

   The measure itself answered an early request for even line ends that the
   frozen stylesheets had already measured and rejected: 85 paragraphs
   across 13 pages with word spaces stretched past twice natural width, the
   worst at 26x. Nothing in the four frozen files justifies a single
   paragraph, which is what they were asserting the whole time. Alignment is
   inherited from each section again, exactly as the frozen files declare
   it: left on the philosophy detail and the story grids, centred on the
   calendar page by this file's own .cal-page rule, and wherever a
   section-head centres its content, its labels follow it again.

   no paragraph anywhere on this site is justified now. If an even-ragged
   request ever returns here, it gets decided on a measured, page-scoped
   rule rather than resurrected from this comment. */

/* ---------- Section 03: the gap left by the removed pull quote ----------

   page-overrides.css labels this rule "Section 03 detail copy under the
   philosophy quote", and that is exactly what it was: the clamp(40px, 5vw, 72px)
   was the space separating the pull quote from the paragraphs beneath it. The
   quote is gone, and so is the section heading that followed it, so the margin
   now separates the welcome brief from the first philosophy heading instead -
   two unrelated blocks, carrying a gap sized for a division that is no longer
   there.

   This is the residue of the removal rather than a design change, which is why it
   is corrected here rather than left. page-overrides.css has to stay
   byte-identical to the static source, and the static source still carries the
   original margin, so the correction cannot live there.

   The value is the site's own section rhythm, clamp(32px, 4.2vw, 48px), stepped
   down because this is a division inside a section rather than between sections.
   No new number is invented: the cap is one step below the figure the site
   already uses everywhere.

   Declared as the margin shorthand rather than margin-top, keeping the collision
   like for like. A longhand against a shorthand compares nothing and the override
   would sit there undeclared, which is the one thing this rule is supposed to prevent.

   The inline margins are 0, not auto. The frozen stylesheet is explicit about this
   box's horizontal position: page-overrides.css 3343 sets margin-inline: 0 here to
   pull the 820px column off the page centre and meet the container's left edge, the same edge the welcome brief above starts from. Copying the auto from the
   older declaration in the same file re-centred the box anyway, because this file
   loads after the frozen one and the shorthand beat margin-inline on file order.
   Left-aligned text inside a centred box is exactly what the client said they do
   not want: the philosophy copy now starts where "Greetings and welcome!" does. */
#philosophy .philosophy-detail { margin: clamp(24px, 3vw, 40px) 0 0; }

/* ---------- Section 02: make the photo and the copy end on the same line ----------

   They did not. The photo is width min(100%, 420px) with a pinned aspect-ratio of
   750/713, so at a wide viewport it is a fixed 399px tall, while the three
   paragraphs beside it shrink as the measure widens - about 293px at 1446 and
   less above that. The grid sets align-items:start, which is why the difference
   lands entirely below the copy rather than being split between the two.

   The mismatch grows with the viewport for the same reason in reverse: the text
   loses lines as the measure widens, and the photo cannot follow because it is
   capped. So the wider the screen, the larger the void on the left.

   The fix makes the text drive. The image is taken out of flow so it stops
   contributing its own height to the grid row, which leaves the copy as the only
   thing setting that height; the figure then stretches to it, and its
   aspect-ratio gives back a width that keeps it circular. The ends line up
   because the row height is now the copy's height rather than the photo's.

   Where the copy is taller than the photo's column allows - a narrow desktop,
   where three paragraphs run long beside a 261px column - the max-width takes
   over and the circle gets smaller instead of stretching into an ellipse. The
   ends stop matching there, which is the right way round: a circle is the design,
   and a circle that has been pulled into an ellipse is worse than a gap.

   Scoped to the two-column layout. Below 769px the grid stacks, the photo sits
   above the copy, and there are no two ends to line up in the first place. */
@media (min-width: 769px) {#meet .welcome-grid { align-items: stretch; }#meet .welcome-media {
    align-self: stretch;
    position: relative;
    margin-inline: auto;
    width: auto;
    max-width: min(100%, 420px);
    aspect-ratio: 750 / 713;
  }#meet .welcome-media img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    aspect-ratio: auto;
  }
}

/* ---------- Section 05: the same defect in the Approach split ----------

   Measured on index.html at 1345px: the media box is 500px and its copy is 367px,
   so 133px of the column ends in nothing. It is the same fault as #meet - a grid
   set to align-items:start whose two columns have different natural heights - and
   the same fix applies. .split-top is the only rule on the site that opts out of
   the centring .split does by default, and #approach is the only place it is used.

   This one also carries a second fault that the first fix clears up. The design
   caps the figure with `max-height: 500px` and gives the image `height: 100%`,
   which cannot work: a percentage height resolves against a definite parent
   height, and max-height is not one. The image therefore falls back to its
   natural 680x708 ratio and renders 538px tall inside a 500px box, so the bottom
   38px is clipped by the figure's overflow:hidden. Taking the image out of flow
   and letting the figure take the row height resolves both: the box is the copy's
   height, the image fills it exactly, and nothing is cut off.

   1025px and up, because .split collapses to one column at 1024px. Below that
   there are no two ends to line up. */

@media (min-width: 1025px) {#approach .split-top { align-items: stretch; }#approach .approach-media img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
  }
}

/* ---------- About: the story grids cannot be made equal, so they are centred ----------

   Measured on about.html at 1345px: the copy is 997px and the portrait is 682px,
   a 315px difference, and the same align-items:start causes it.

   Equal ends are not reachable here, and pretending otherwise would break the
   design. .story-media carries aspect-ratio 4/5 inside a 517px column, so its
   height is fixed by its width. To reach 997px it would have to grow to 798px wide
   - wider than its column by 281px - or stretch into a 0.52 ratio portrait against
   a design that asks for 0.8. The image cannot shrink either, because the text
   is the taller of the two. So centring is the correct answer rather than the
   requested one: the 315px becomes 157px above and below, and the portrait reads
   as a deliberate offset beside a long block of prose instead of as a column that
   stopped early.

   769px and up, which is where .story-grid is still two columns. */
@media (min-width: 769px) {.about-page .story-grid { align-items: center; }
}/* ---------- Phones: the smallest text and the smallest tap targets ----------

   Measured across 20 pages at 320, 375 and 414px in a real engine, by putting
   each page in a same-width frame. There is no horizontal overflow anywhere, so
   the layout is sound; what the sweep found is size, at the narrow end only.

   .btn carries 0.68rem at its narrowest, which is 10.88px - the button's own text
   below the 12px floor, measured on the 404 page's "Contact Me". The design
   already uses 0.75rem for .btn-gold in the same block, so this is not a new
   number invented for the correction; it is the value the sibling rule already
   uses, applied to the base class that was left behind.

   .cic-label is 0.6rem, or 9.6px, and is the smallest text anywhere on the site:
   the "Email" and "Phone" captions in the contact cards. .chip and .hook-label
   sit at 0.7rem. All three are lifted to the next value already present in the
   stylesheets rather than to one chosen here.

   The tap target is a separate defect and the only genuine WCAG failure the sweep
   produced. Two of the contact card links - the phone numbers - are 112x22 at
   320px, under the 24px minimum, and they are close enough together that the
   spacing exception does not save them. Every other undersized target on the site
   passes it: there are around 230 of them, nearly all 18px navigation links, but
   a 24px circle centred on each one clears its neighbours. min-height gives them
   the size without disturbing the type.

   768px and down, which is where the design's own narrow rules apply. Above that
   the site already renders larger than this and nothing here should change.

   Every selector below carries a body prefix, and that is load-bearing rather than
   decoration. breakpoints.css is enqueued after this file, and it is the file that
   sets .btn, .cic-label and .hook-label to these sizes. Written as bare
   class names they match at equal specificity, so the later file wins on order and
   the correction silently does nothing. The body prefix lifts them to 0,1,1 and
   they win on specificity instead, which is what makes this layer able to correct
   the responsive rules at all.

   The first attempt at this was written without the prefix and measured as having
   changed nothing, which is worth recording: a rule that loses the cascade looks
   exactly like a rule that was never needed. */

@media (max-width: 768px) {body .btn { font-size: 0.75rem; }body .cic-label { font-size: 0.7rem; }body .cic-value { min-height: 24px; }body body .hook-label { font-size: 0.75rem; }
}

/* ---------- Reading measure: the theme follows the shared measure ----------

   theme-wp.css used to widen .section > .container below 1025px to undo the
   doubled inset in the frozen stylesheets. It made the phone measure roomier,
   but it also pulled every band wider than its static twin: at a 1000px
   viewport the home page container measured 958px here against 798px on
   index.html, and the Approach photograph rendered 958x500 instead of
   798x500. The theme is a mirror of the static pages and must not land on a
   different measure from the one the shared files were tuned to, so the
   override is gone and the frozen width rules apply unchanged. */

/* ---------- Services: the coaching image follows its copy at every width ----------

   This is the root cause of the ragged column end on this page, and it is the same
   fault as #approach, which is why it survived the first pass: that one was found
   at 1345px and this one only appears at the narrow end of the two-column range.

   page-overrides.css writes

     #coaching .split-media { align-self: stretch; max-height: 500px; }

   and those two declarations defeat each other. align-self: stretch grows an item
   to the row height, and max-height stops it growing past 500px. Whenever the
   copy beside it is taller than 500px the item cannot reach the row height, and a
   stretch that cannot reach the row falls back to aligning at the start. So the
   declaration that was written to make the image fill its column is the very
   declaration that pins it to the top whenever the text runs long.

   Measured across the widths, and the pattern is only visible once you look at the
   ends of the range:

     320-768px   one column, the image is a banner above the copy, nothing to align
     1025px      two columns, copy 654px against media 500px, 154px ragged
     1446px      two columns, copy 500px against media 500px, matches

   1446px agrees by coincidence - the copy happens to land on 500px at that
   measure. Nothing enforces it. Widen or narrow the window and the two part
   company again, which is exactly the complaint.

   The fix removes the cap rather than working around it, because the cap was only
   ever there to stop the photograph growing unreasonable, and object-fit: cover
   on the image already handles that by cropping instead of stretching. With the
   cap gone the align-self: stretch that was already declared does the job it was
   written for, and the image tracks the copy at every width instead of at one.

   The image is taken out of flow so the figure contributes no height of its own.
   Without that, the figure would keep its own height, set the row height, and
   stretch to a row it had already decided - a circular rule that resolves to the
   same 500px it started at.

   1025px and up, which is where .split is two columns. Below that the grid
   stacks, the image is a banner in its own row, and the 500px cap is doing exactly
   what it was written to do: keeping a full-bleed photograph from becoming a
   900px-tall block on a phone. It is left in place there. */

@media (min-width: 1025px) {#coaching .split-media {
    max-height: none;
    height: 100%;
  }#coaching .split-media img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
  }
}/* ---------- Scheduler iframe height ----------

   This rule used to live in breakpoints.css, directly under the reset it fights.
   That was the wrong file: the four CSS files shared with the static site have to
   stay byte-identical, and a theme-only fix inside one of them means the two
   copies drift and the drift is invisible until somebody compares them.

   It works from here, in theme-wp.css, even though that loads before
   breakpoints.css rather than after it. Order is not what decides this, specificity
   is. The reset is "img, video, embed, iframe, object" at (0, 0, 1); this is
   ".calendly-inline-widget iframe" at (0, 1, 1), which outranks it wherever the two
   are written. It is the only rule in breakpoints.css that sets a height on an
   iframe, so there is nothing else for it to lose to.

   Why it is needed: height:auto is a sensible reset for images and for embedded
   media that should keep its own aspect ratio, and it is what stops a wide image
   forcing a horizontal scrollbar. On an iframe whose height is a deliberate, chosen number it destroys that number, because the iframe reports no intrinsic
   ratio and auto collapses to the HTML default of 150px.

   That is what happened to the booking calendar. The scheduler container is 800px
   and correctly sized; the iframe inside it was forced to 150px, so the visitor saw
   a box a tenth of the height they were meant to, with the calendar cut off below
   the month grid and the time-slot list, the whole reason the page exists, off the
   bottom. It did not look like a CSS bug. The frame was there, the calendar rendered
   inside it, the box had the right width, and the page returned 200. It looked like
   Calendly had served a short calendar.

   The fix restores what the element actually carries: Calendly writes height="100%"
   on the iframe it creates, which resolves against the 800px container. It is scoped
   to the widget rather than applied to every iframe, because a blanket iframe reset
   would undo height:auto for the YouTube embeds and anything else that genuinely does
   rely on the ratio. */
/* ---------- Scheduler iframe height ----------
... (existing) */
.calendly-inline-widget iframe { height: 100%; }.calendly-inline-widget { transition: height .25s ease; }/* ---------- Booking card: sized scheduler ----------: sized scheduler ----------
   The calendar page wraps the embed in a .booking-card so the scheduler has a
   proper width and a bounded height instead of stretching edge to edge. */.booking-card { width: 100%; max-width: 1400px; margin: 0 auto; overflow: hidden; background: #FFFFF5; border: 1px solid rgba(34, 84, 76, 0.16); border-radius: 20px; box-sizing: border-box; }.booking-content { width: 100%; padding: 0; box-sizing: border-box; }.booking-card .calendly-inline-widget { width: 100% !important; min-width: 0 !important; height: 850px; background: #FFFFF5; box-sizing: border-box; }@media (min-width: 1200px) { .booking-card { max-width: 1600px; } .booking-card .calendly-inline-widget { height: 900px; } }@media (max-width: 600px) { .booking-card { width: 100%; border-radius: 12px; } .booking-card .calendly-inline-widget { height: 850px; } }/* Text overflow fix for the time zone notice and long unbroken strings. */.bk-scheduler-tz, .booking-card, .entry-content { word-break: break-word; overflow-wrap: anywhere; box-sizing: border-box; }/* ---------- Calendar page: full-bleed scheduler ----------
   The static calendar page runs the Calendly embed edge to edge, so the theme's
   scheduler does the same. The container is widened to the full viewport and the
   widget, already declared 100% wide, fills it. The text lines keep their
   centred, width-capped measures from the rules above. */
.cal-page > .container { width: 100%; max-width: none; }

/* ---------- Packages: the split pricing design, 4.104.0 ---------- client supplied a pricing design and a comparison table with the two
   package columns, and asked for the table's data inside that design. The
   design is one dark featured card on the left and a stack of plan rows on
   the right, so the page is rebuilt around that: the flagged package takes
   the card, every other package becomes a row, and the stack carries two
   further rows for offers this page already makes, the free discovery call
   and the 3-months follow-up, each one linking to the section it summarises.

   The class names are new, on purpose. The old cards were .service-card with
   .pkg-card on top, and the frozen stylesheet carries a long, careful set of
   rules for exactly that pair: .service-card .body > p sets colour and size
   on every direct paragraph in a card, and .page-packages .pkg-card .body
   centres the card text at (0, 3, 1), with .pkg-badge, .pkg-meta, .pkg-price
   and .pkg-for each pulled back onto their tokens at (0, 2, 1) and above. Every
   one of those rules was written to make the old white cards look right. This
   section is a different object, so it does not wear their names and cannot
   be argued with by them.

   Ink on the dark card, all of it measured against --charcoal (#201C16):
   --white is 15.9:1 and --ivory 15.4:1, both far past AA. The secondary
   lines are --ivory at 78% over the card, which lands near 8:1, and the
   caption at 72%, near 7:1. The ticks are --gold-soft (#E4EFEB) at about
   13:1. The call to action is .btn-gold, which is the site's own gold
   button: white on --gold is 8.6:1, the same figure the frozen stylesheet
   records for that pair.

   Nothing here sets an alignment of its own beyond the price block sitting
   right against the arrow. Card copy inherits, the way the rest of the site
   does since the justify measure was removed in 4.103.0. */

/* The stack is the wider of the two columns, which is the supplied design's
   own proportion (its dark card runs about a third of the width, its stack
   about two thirds). A 560px stack made the row's head wrap at desktop: the
   name and its badge, the price and the arrow, together needed more than the
   column had, so the price block dropped to a second line stranded left of
   the arrow. Wider is also what lets the row's head keep name and price on
   one line at 1446, the only width at which it used to break. */
.pk-duo {
  display: grid;
  grid-template-columns: minmax(0, 0.86fr) minmax(0, 1.14fr);
  gap: clamp(16px, 1.6vw, 24px);
  align-items: stretch;
}/* ---------- The featured card ---------- */
.pk-hero {
  display: flex;
  flex-direction: column;
  /* The card and the stack beside it are told to the same height, and the
     stack is the taller of the two, so the card's groups are spread over the
     height it is given rather than leaving one void in the middle of it. The
     supplied design's card is content-dense, and this is the same answer for
     a card that carries less: the space sits between the groups, where it
     reads as breathing room, and not under the checklist, where it reads as
     a mistake. */
  justify-content: space-between;
  background: var(--charcoal);
  color: var(--ivory);
  border-radius: var(--radius-lg);
  padding: clamp(24px, 2.6vw, 40px);
}.pk-hero-top {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 14px;
}/* The badge sits above the title rather than beside it. Beside it, on this
   card's width, the pill took 114px out of a 232px line and the title could
   only fit at 17px; above it, the title takes the card's full width and keeps
   a size of its own. Right-aligned, so it still reads as the card's own
   corner marker. */
.pk-badge--hero {
  align-self: flex-end;
  background: transparent;
  color: var(--ivory);
  border: 1px solid rgba(251, 248, 243, 0.34);
}.pk-hero-title {
  display: flex;
  align-items: flex-start;
  gap: 14px;
}.pk-hero-icon {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: rgba(251, 248, 243, 0.1);
  color: var(--gold-soft);
  font-size: 1.2rem;
}.pk-hero-title h3 {
  font-family: var(--font-display);
  font-weight: 700;
  /* The card's own width is the limit here. Beside a badge the title had
     232px, which is 17px of type; with the badge moved above it the title
     takes the card's full width, and 1.6rem is the largest size that still
     fits the longest name the page carries on one line. */
  font-size: clamp(1.4rem, 1.85vw, 1.6rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--white);
  margin: 0 0 8px;
}.pk-hero-for {
  margin: 0;
  max-width: 46ch;
  font-size: 0.95rem;
  line-height: 1.6;
  color: rgba(251, 248, 243, 0.8);
}/* The card's Best For line carries its own label, the way the client's table
   does, so the reader can tell an audience sentence from a feature. The label
   is the card's one light-weight emphasis; everything else on the card speaks
   through size. */
.pk-hero-for strong {
  font-weight: 600;
  color: var(--ivory);
}.pk-hero-mid { margin-top: clamp(18px, 2vw, 26px); }.pk-price {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2.4rem, 4.6vw, 3.4rem);
  line-height: 0.95;
  letter-spacing: -0.03em;
  color: var(--white);
}.pk-price-note {
  margin: 10px 0 0;
  max-width: 44ch;
  font-size: 0.8rem;
  line-height: 1.6;
  color: rgba(251, 248, 243, 0.72);
}.pk-cta { margin-top: clamp(18px, 2vw, 26px); }.pk-includes {
  margin-top: clamp(18px, 2vw, 26px);
  padding-top: clamp(18px, 2vw, 24px);
  border-top: 1px solid rgba(251, 248, 243, 0.18);
}/* ---------- The labelled detail rows ----------
   The client's comparison table has seven rows, and each plan now carries all
   seven of them under its own name rather than as one undifferentiated tick
   list: Best For (which the card puts on its own line above the price), then
   Format, Duration, Meetings and Access, Core Focus and Real-Life Practice
   here, with Payment Options as the price block. The rows are a definition
   list so the label and the sentence stay visually separate even when the
   sentence runs to three lines. */
.pk-spec {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 16px 20px;
  margin: 0;
}.pk-spec dt {
  font-family: var(--font-ui);
  font-size: 0.66rem;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(251, 248, 243, 0.62);
  padding-top: 0.35em;
}.pk-spec dd {
  margin: 0;
  font-size: 1rem;
  line-height: 1.6;
  color: rgba(251, 248, 243, 0.92);
}.pk-spec dd .pk-list { display: grid; gap: 6px; }.pk-list-label {
  margin: 0 0 14px;
  font-family: var(--font-ui);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(251, 248, 243, 0.62);
}/* ---------- The checklist, on the card and in the rows ---------- */
.pk-list {
  list-style: none;
  margin: 0;
  padding: 0;
}.pk-list li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 0.92rem;
  line-height: 1.55;
}.pk-list li i {
  flex: 0 0 auto;
  margin-top: 0.2em;
  font-size: 0.95rem;
  color: var(--gold-soft);
}/* ---------- The stack of plan rows ---------- */
.pk-rows {
  display: flex;
  flex-direction: column;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
}.pk-row {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: clamp(14px, 1.6vw, 18px);
  padding: clamp(20px, 2.2vw, 30px);
  flex: 1 1 auto;
}.pk-row + .pk-row { border-top: 1px solid var(--line); }.pk-row--highlight { background: var(--ivory-2); }/* The head carries the name on the left and the payment options on the right, and the detail rows take the full width below them. Splitting the row into
   two bands is what lets seven labelled rows fit: the old side-by-side split
   left the detail a column about 280px wide, where every sentence in it
   collapsed into five or six lines. */
.pk-row-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px 16px;
}.pk-row-title {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
}.pk-row-head h3 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.12rem;
  letter-spacing: -0.01em;
  color: var(--ink);
}.pk-badge {
  display: inline-block;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--gold-soft);
  color: var(--gold);
  font-family: var(--font-ui);
  font-size: 0.64rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
}/* The rows' detail block, tighter than the card's: the card is one plan given
   a whole panel, the rows are two plans sharing one stack, and the tighter
   rhythm is what keeps the two columns within about 150px of each other
   instead of double. */
.pk-row .pk-spec {
  gap: 8px 18px;
}.pk-row .pk-spec dt {
  font-size: 0.62rem;
  color: var(--charcoal-2);
}.pk-row .pk-spec dd {
  font-size: 0.88rem;
  line-height: 1.55;
  color: var(--ink);
}/* --muted is 4.9:1 on white but only 4.25:1 on the tinted row, which is under
   AA for the small print it carries, so the label and the small print take
   --charcoal-2 at 10.8:1 and keep their place in the hierarchy by size and
   case instead. */
.pk-row .pk-list li {
  font-size: 0.85rem;
  color: var(--charcoal-2);
}.pk-row .pk-list li i { color: var(--gold); }/* ---------- Price and arrow ---------- */
/* The name and the price keep one line at desktop, and the price block is
   anchored right either way: on the same line the free space puts it there, and when a long name does push it to the second line the auto margin puts
   it there too, so it never sits stranded under the left edge. */
.pk-row-buy {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-left: auto;
}.pk-row-price { text-align: right; }.pk-price-sm {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1rem, 1.35vw, 1.18rem);
  letter-spacing: -0.02em;
  color: var(--ink);
  white-space: nowrap;
}.pk-row-note {
  margin: 4px 0 0;
  font-size: 0.72rem;
  color: var(--charcoal-2);
}.pk-go {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--white);
  color: var(--ink);
  text-decoration: none;
  transition: background 0.3s var(--ease), color 0.3s var(--ease), border-color 0.3s var(--ease);
}.pk-go i { font-size: 1rem; }.pk-go:hover, .pk-go:focus-visible {
  background: var(--gold);
  border-color: var(--gold);
  color: var(--white);
}/* The card breathes: it floats a few pixels and its shadow deepens into a gold
   glow on the same rhythm, so the eye keeps landing on the dark panel even
   when nothing is being hovered. Paused on hover, where the static shadow
   takes over and the row-level motion steps back. */
.pk-hero {
  animation: pk-card-float 4.2s ease-in-out infinite, pk-card-glow 4.2s ease-in-out infinite;
}.pk-hero:hover {
  animation-play-state: paused;
  box-shadow:
    0 48px 96px -16px rgba(34, 84, 76, 0.55),
    inset 0 1px 0 rgba(255, 255, 255, 0.18);
}.pk-row {
  transition:
    transform 0.45s cubic-bezier(0.32, 0.72, 0, 1),
    background-color 0.35s cubic-bezier(0.32, 0.72, 0, 1),
    box-shadow 0.35s cubic-bezier(0.32, 0.72, 0, 1);
}.pk-row:hover {
  transform: translateY(-2px);
  background: var(--white);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.75);
}.pk-row--highlight:hover { background: var(--white); }.pk-row-buy .pk-go {
  transition:
    background-color 0.35s cubic-bezier(0.32, 0.72, 0, 1),
    color 0.35s cubic-bezier(0.32, 0.72, 0, 1),
    border-color 0.35s cubic-bezier(0.32, 0.72, 0, 1),
    transform 0.35s cubic-bezier(0.32, 0.72, 0, 1);
}.pk-go i {
  transition: transform 0.35s cubic-bezier(0.32, 0.72, 0, 1);
}.pk-row:hover .pk-go {
  background: var(--gold);
  border-color: var(--gold);
  color: var(--white);
  transform: translateY(-1px);
}.pk-row:hover .pk-go i { transform: translateX(3px); }.pk-cta {
  transition:
    transform 0.35s cubic-bezier(0.32, 0.72, 0, 1),
    box-shadow 0.35s cubic-bezier(0.32, 0.72, 0, 1);
}.pk-cta .arw {
  display: inline-flex;
  transition: transform 0.35s cubic-bezier(0.32, 0.72, 0, 1);
}.pk-cta:hover {
  transform: translateY(-1px);
  box-shadow: 0 14px 28px -10px rgba(34, 84, 76, 0.55);
}.pk-cta:hover .arw { transform: translate(3px, -2px); }.pk-cta:active { transform: translateY(0) scale(0.985); }.pk-badge {
  transition: background-color 0.3s cubic-bezier(0.32, 0.72, 0, 1), color 0.3s cubic-bezier(0.32, 0.72, 0, 1);
}.pk-row:hover .pk-badge {
  background: var(--gold);
  color: var(--white);
}

@media (prefers-reduced-motion: reduce) {.pk-hero, .pk-row, .pk-go, .pk-go i, .pk-cta, .pk-cta .arw, .pk-badge, .pk-badge--hero {
    transition: none !important;
    transform: none !important;
  }
}/* The third package's anchor joins the other pricing anchors, which the frozen
   stylesheet offsets from the fixed header. That file cannot change, and the
   new id is not in its list, so it is offset here with the same value. */

/* The focus ring the polish section above dropped on its way in. */
.pk-go:focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; }animates only transform or opacity, sits behind the content, and is disabled
   under prefers-reduced-motion. */
.pk-hero {
  position: relative;
}/* The breathing spotlight in the card's upper right. */
.pk-hero::after {
  content: '';
  position: absolute;
  top: -25%;
  right: -20%;
  width: 70%;
  height: 80%;
  background: radial-gradient(circle, rgba(255, 255, 255, 0.22) 0%, rgba(255, 255, 255, 0) 65%);
  animation: pk-breathe 4.5s ease-in-out infinite;
  z-index: 0;
  pointer-events: none;
}/* White edges: a soft white inset border that breathes around the card's
   perimeter, drawing the eye to the panel without crossing its interior.
   Not rotating: it pulses in place. */
.pk-hero::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);
  animation: pk-edge-white 3.2s ease-in-out infinite;
  z-index: 0;
  pointer-events: none;
}.pk-hero > * { position: relative; z-index: 1; }/* The icon floats, the badge pulses its gold ring. */
.pk-hero-icon {
  animation: pk-float 3.2s ease-in-out infinite;
}.pk-badge--hero {
  animation: pk-badge-pulse 2.2s ease-in-out infinite;
}/* The gold button shimmers. */
.pk-cta {
  position: relative;
  overflow: hidden;
}.pk-cta::before {
  content: '';
  position: absolute;
  top: 0;
  left: -70%;
  width: 50%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent);
  animation: pk-shimmer 3.8s ease-in-out infinite;
  pointer-events: none;
  z-index: 0;
}.pk-cta > * { position: relative; z-index: 1; }/* The rows' gold ticks breathe together. */
.pk-row .pk-list li i {
  animation: pk-tick 2.6s ease-in-out infinite;
}

@keyframes pk-card-float {0%, 100% { transform: translateY(0); }50% { transform: translateY(-7px); }
}
@keyframes pk-card-glow {0%, 100% {
    box-shadow:
      0 32px 64px -20px rgba(0, 0, 0, 0.45),
      0 0 0 0 rgba(251, 248, 243, 0),
      inset 0 1px 0 rgba(255, 255, 255, 0.08);
  }50% {
    box-shadow:
      0 48px 96px -12px rgba(34, 84, 76, 0.5),
      0 0 0 6px rgba(251, 248, 243, 0.18),
      inset 0 1px 0 rgba(255, 255, 255, 0.18);
  }
}
@keyframes pk-breathe {0%, 100% { opacity: 0.55; transform: scale(0.96); }50% { opacity: 1; transform: scale(1.04); }
}
@keyframes pk-edge-white {0%, 100% { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.06); }50% { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.32); }
}
@keyframes pk-float {0%, 100% { transform: translateY(0); }50% { transform: translateY(-5px); }
}
@keyframes pk-badge-pulse {0%, 100% { opacity: 0.85; }50% { opacity: 1; }
}
@keyframes pk-shimmer {0% { left: -70%; }100% { left: 170%; }
}
@keyframes pk-tick {0%, 100% { opacity: 0.75; transform: scale(1); }50% { opacity: 1; transform: scale(1.12); }
}

@media (prefers-reduced-motion: reduce) {.pk-hero, .pk-hero::after, .pk-hero::before, .pk-hero-icon, .pk-badge--hero, .pk-cta::before, .pk-row .pk-list li i {
    animation: none !important;
  }
}/* The third package's anchor joins the other pricing anchors, which the frozen
   stylesheet offsets from the fixed header. That file cannot change, and the
   new id is not in its list, so it is offset here with the same value. */
#executive-intensive { scroll-margin-top: calc(var(--header-h, 76px) + 24px); }

/* ---------- Narrow screens ---------- */
@media (max-width: 1100px) {.pk-duo { grid-template-columns: 1fr; }
}
@media (max-width: 720px) {/* The label stops sitting beside its sentence and stacks above it, which is
     what keeps a 15-letter label like Real-Life Practice from eating the whole
     width of a phone-sized row. */
  .pk-spec { grid-template-columns: 1fr; gap: 3px; }.pk-spec dt:not(:first-child) { padding-top: 12px; }.pk-row-head { flex-direction: column; align-items: stretch; }.pk-row-buy { width: 100%; margin-left: 0; justify-content: space-between; }.pk-row-price { text-align: left; }.pk-go { width: 42px; height: 42px; }
}

/* ---------- Hero credential pills ----------
   The two role labels under the headline were reduced to a flat 10px in the
   frozen stylesheet and read as a footnote beside the 50px headline. The
   client asked for them to come back up to a medium-large size, scaled in
   proportion to the heading rather than fixed: 15.2px at the floor, 20px at
   1440. Padding is set in em so the pill grows as one unit with its type
   instead of the text swelling inside an unchanged box, and line-height is
   tightened to 1.25 so the taller pill stays a label, not a banner.

   The phone rule repeats the selector with a body prefix on purpose. The
   0.62rem rule in the frozen breakpoints file is (1,2,1) and loads last, so
   an equal-specificity override here would lose; the extra element takes
   this rule to (2,2,1) and it wins wherever it applies. */
body #hero.hero--tint .hero-roles span {
  font-size: clamp(0.95rem, 1.4vw, 1.25rem);
  line-height: 1.25;
  padding: 0.45em 0.9em;
  /* The frozen rule draws a 55%-white hairline around each pill. The client
     asked for no white border, so it is kept at 1px to hold the box size and
     made transparent rather than removed. */
  border-color: transparent;
}
/* ---------- Hero green gradient overlay ----------
   The home hero mask is a brand tint instead of a flat black veil: a green
   gradient that runs from the deep teal on the left to bare image on the
   right, so the photograph fades into the palette rather than sitting under
   smoke. rgba(34,84,76) is the --gold token (22544C) the pills and buttons
   use. It sits above the image (z-index 1) but below the copy (z-index 2),
   and the hero's overflow:hidden + rounded corners clip it to the curve. */
#hero.hero--full .hero-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(90deg,
    rgba(34, 84, 76, 0.52) 0%,
    rgba(34, 84, 76, 0.3) 50%,
    rgba(34, 84, 76, 0.05) 100%);
}
@media (max-width: 576px) {
  body #hero.hero--tint .hero-roles span {
    font-size: 0.8rem;
    line-height: 1.35;
    padding: 0.5em 0.85em;
  }
}
/* ---------- Approach image height ---------- */
#approach .approach-media { height: 500px !important; max-height: none !important; }
#approach .approach-media img { height: 100% !important; }
/* ---------- Process lead centred under its heading ----------
   The frozen page-overrides.css pins #the-process .section-head .lead to
   margin-inline: 0, holding a 620px box on the container's left edge while its
   text stays centred, so the lead hangs off-centre below the centred "What we
   actually do together" heading. Auto margins re-centre the box so the lead
   lines up with the heading. Static carries the same declaration inline. */
#the-process .section-head .lead { margin-inline: auto; }

/* About credentials lead. The section heading above it was removed at the
   client's request, so the sentence now stands alone in the head - and the
   .lead caps (52ch from design-tokens.css, tighter still from the removed
   narrow-600 wrapper) wrapped it into two lines where the page shows every
   other head as one. The sentence is about 87 characters, well under the
   container measure, so max-width: none lifts the cap and it reads as one
   centred line; layout.css already gives .section-head.center .lead its
   margin-inline: auto. Mirrored in about.html's inline style. */
#credentials .section-head .lead { max-width: none; }

/* ---------- Packages: three equal cards, 4.133.0 ----------
   The client asked for the other plans to carry the featured card's own
   style, so the pk-duo split (dark card left, .pk-rows stack right) is
   retired on this page: every package now renders the same .pk-hero card,
   side by side in .pk-cards. The grid keeps equal heights so the three
   cards' foot lines land together, and below 1100px the row collapses to a
   single column the way the pk-duo split always did. The pk-duo and pk-rows
   rules further up stay in the file only as the fallback for a saved package
   set rendered through an older template copy. */
.pk-cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(16px, 1.6vw, 24px);
  align-items: stretch;
}
@media (max-width: 1100px) {
  /* minmax(0, 1fr) instead of 1fr: a bare 1fr track keeps the item's min-content
     as its automatic minimum, so an unbreakable line could widen the track past
     the container and hang the card off a 320px viewport. */
  .pk-cards { grid-template-columns: minmax(0, 1fr); }
}

/* ---------- Packages: the fee block, 4.136.0 ----------
   The payment note dropped out of the caption at 0.8rem grey, so the actual
   fee the client prices in (USD, then PKR, then the free discovery call)
   read as a footnote under the huge price word. Inside the card it is now a
   fee block on its own: the parenthesised arrangement line stays small and
   soft, the two amount lines step up to display-weight money, and the free
   call line sits last with a check mark in the gold tone. The template
   classifies each note line by its opening characters, so a note edited in
   the dashboard keeps the same structure. */
.pk-price-note {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin: 12px 0 0;
  max-width: none;
  font-size: 1rem;
  line-height: 1.45;
}
.pk-price-note .pk-fee-soft {
  font-size: 0.92rem;
  color: rgba(251, 248, 243, 0.72);
}
.pk-price-note .pk-fee-amount {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.55rem;
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--white);
}
.pk-price-note .pk-fee-free {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 2px;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--gold-soft);
}
.pk-price-note .pk-fee-free i {
  font-size: 1.1em;
}

/* ---------- Packages: card interior polish, 4.137.0 ----------
   Three repairs for the three-equal-cards layout:

   1. The spacing. .pk-hero kept justify-content: space-between, which was
      written for a two-group card (top content, price block). With three
      groups it centred the Plan details block and left a hole above and
      below it in every card, worst where the details were shortest. The
      card now reads top to bottom naturally and the price group is pinned
      to the card's foot with margin-top: auto, so the three cards' fee
      blocks land on one line and spare height collects in exactly one
      place, between the details and the fee.

   2. The detail rows. The shared .pk-spec is a max-content label column
      beside a value column, sized for the half-page rows of the old split
      design. Inside a 390px card the "REAL-LIFE PRACTICE" labels ate the
      width and every value wrapped into a tall narrow column. In the card
      the label stacks above its value instead: a small, evenly capped
      kicker line, then the sentence under it at reading size, each pair
      separated, new pairs spaced a step apart.

   3. The price word. 3.4rem was sized for a card two-thirds of the page
      wide; in a third-width column it ran edge to edge. Stepped down to a
      2.6rem ceiling here, still the loudest line on the card. */
.pk-hero { justify-content: flex-start; }
.pk-hero-mid { margin-top: auto; padding-top: clamp(18px, 2vw, 26px); }
.pk-hero .pk-price { font-size: clamp(1.9rem, 2.8vw, 2.6rem); }
.pk-hero .pk-spec {
  display: grid;
  grid-template-columns: 1fr;
  gap: 3px;
}
.pk-hero .pk-spec dt {
  padding-top: 0;
  font-size: 0.6rem;
  letter-spacing: 0.12em;
  color: rgba(251, 248, 243, 0.55);
}
.pk-hero .pk-spec dt:not(:first-child) { padding-top: 12px; }
.pk-hero .pk-spec dd {
  font-size: 0.95rem;
  line-height: 1.55;
}

/* ---------- Packages: the light yellow card, device-scaled (2026-10-27) ----------
   The client asked for the plan cards on a light white-yellow instead of
   charcoal, with type that steps down by device. The card yellow is the
   pale #FFFEF8; it sits close to the page's own --butter, so the card keeps
   a hairline edge and its shadows for definition, and every white ink
   inside it is retinted to charcoal here rather than each earlier rule
   being rewritten: these come later, later rules win, and an older template
   copy still renders the charcoal card unchanged. --charcoal reads 15:1 on
   the yellow, and the green .btn-gold CTA keeps its own. */
.pk-hero {
  background: #FFFEF8;
  color: var(--charcoal);
  border: 1px solid rgba(32, 28, 22, 0.12);
}
.pk-hero::after {
  background: none;
}
.pk-hero::before {
  box-shadow: inset 0 0 0 1px rgba(32, 28, 22, 0.08);
}
@keyframes pk-edge-white {0%, 100% { box-shadow: inset 0 0 0 1px rgba(32, 28, 22, 0.08); }50% { box-shadow: inset 0 0 0 1px rgba(32, 28, 22, 0.16); }
}
/* White effects come off the cards at the client's request (2026-10-27):
   no white inset highlight, no white spread ring, no white sweep on the
   button. The float keeps a plain soft shadow underneath. */
@keyframes pk-card-glow {0%, 100% {
    box-shadow: 0 18px 36px -20px rgba(32, 28, 22, 0.16);
  }50% {
    box-shadow: 0 26px 52px -18px rgba(32, 28, 22, 0.22);
  }
}
.pk-hero:hover {
  animation-play-state: paused;
  box-shadow: 0 30px 60px -18px rgba(32, 28, 22, 0.24);
}
.pk-cta::before {
  content: none;
}
.pk-badge--hero {
  color: var(--charcoal);
  border-color: rgba(32, 28, 22, 0.4);
}
.pk-hero-icon {
  background: rgba(32, 28, 22, 0.08);
  color: var(--gold);
}
.pk-hero-title h3 { color: var(--charcoal); }
.pk-hero-for { color: rgba(32, 28, 22, 0.8); }
.pk-hero-for strong { color: var(--charcoal); }
.pk-price { color: var(--charcoal); }
.pk-price-note { color: rgba(32, 28, 22, 0.72); }
.pk-price-note .pk-fee-soft { color: rgba(32, 28, 22, 0.75); }
.pk-price-note .pk-fee-amount { color: var(--charcoal); }
.pk-price-note .pk-fee-free { color: var(--gold); }
.pk-includes { border-top-color: rgba(32, 28, 22, 0.25); }
.pk-hero .pk-spec dt { color: rgba(32, 28, 22, 0.6); }
.pk-hero .pk-spec dd { color: var(--charcoal); }
.pk-hero .pk-list li i { color: var(--gold); }

/* The device steps. Middle widths slim the card before the grid collapses,
   and at phone width every face of the card steps down: padding, icon,
   headings, fee block, list, so the longest plan still reads without a
   horizontal strip. */
@media (max-width: 1100px) {
  .pk-hero { padding: 26px; }
  .pk-hero .pk-price { font-size: 2.2rem; }
  .pk-price-note .pk-fee-amount { font-size: 1.4rem; }
}
@media (max-width: 720px) {
  .pk-hero { padding: 20px; }
  .pk-hero-top { gap: 10px; }
  .pk-hero-title { gap: 10px; }
  .pk-hero-title h3 { font-size: 1.2rem; margin: 0 0 5px; }
  .pk-hero-for { font-size: 0.9rem; }
  .pk-hero-icon { width: 36px; height: 36px; border-radius: 10px; font-size: 1rem; }
  .pk-hero .pk-spec dd { font-size: 0.9rem; }
  .pk-list li { font-size: 0.86rem; }
  .pk-hero .pk-price { font-size: 1.9rem; }
  .pk-price-note .pk-fee-amount { font-size: 1.25rem; }
  .pk-price-note .pk-fee-free { font-size: 0.88rem; }
}

/* ---------- Packages: the pair spread (2026-10-27) ----------
   The equal-height cards pinned the fee block to the foot, and the whole
   spare height of the shorter plans sat as one hole between the details
   and the fee. Each spec row is now its own pair (a div inside the dl,
   which carries the dt/dd groups) and the pairs spread across the details
   zone, so the spare space sits evenly between the rows instead of pooling
   in one place. The fee block keeps its divider line and a balanced wrap
   for the session-basis line. Scoped to .pk-hero; the retired .pk-row
   cards keep their own flat spec layout. */
.pk-hero .pk-includes {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
}
.pk-hero .pk-spec {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 12px;
}
.pk-hero .pk-spec dt { padding-top: 0; }
.pk-hero .pk-hero-mid {
  border-top: 1px solid rgba(32, 28, 22, 0.18);
}
.pk-price { text-wrap: balance; }

/* ---------- Packages: the reference card, US$/PKR toggle, featured middle (2026-10-27) ----------
   The client supplied a reference: the icon chip above the title, the big
   price right under it, the CTA under the price, a divider, and the detail
   rows closing the card; the middle card stays the featured dark one. The
   card already paints #FFFEF8 from the block above, so the order is set with
   flex margins rather than the markup being rewritten, and the original
   charcoal values come back on the middle card here. */
.pk-currency {
  display: flex;
  justify-content: center;
  gap: 4px;
  width: max-content;
  margin: 0 auto clamp(18px, 2vw, 26px);
  padding: 4px;
  background: #FFFFFF;
  border: 1px solid var(--line);
  border-radius: 999px;
}
.pk-currency button {
  appearance: none;
  border: 0;
  background: transparent;
  padding: 8px 18px;
  border-radius: 999px;
  font-family: var(--font-ui);
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--ink);
  cursor: pointer;
}
.pk-currency button.active {
  background: var(--charcoal);
  color: var(--ivory);
}
.pk-currency button:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 2px;
}

/* The big price line carries the two currency spans; the grid's data-cur
   decides which one shows. The fees are per session, so no annual toggle
   exists. */
.pk-price { display: block; }
.pk-price .pk-fee-usd,
.pk-price .pk-fee-pkr { display: block; }
.pk-cards[data-cur="pkr"] .pk-fee-usd { display: none; }
.pk-cards[data-cur="usd"] .pk-fee-pkr { display: none; }

/* The session basis leads the fee note as a small caption. */
.pk-fee-cap {
  display: block;
  font-family: var(--font-ui);
  font-size: 0.66rem;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(32, 28, 22, 0.62);
}

/* The reference order: identity, then price and CTA, then details close the
   card. Scoped to .pk-cards so the retired pk-duo fallback keeps its own
   arrangement, and the divider moves with the details block. */
.pk-cards .pk-hero-top { order: 1; }
.pk-cards .pk-hero-mid {
  order: 2;
  margin-top: clamp(14px, 1.6vw, 20px);
  padding-top: 0;
  border-top: 0;
}
.pk-cards .pk-includes { order: 3; }

/* The microcopy under the grid. */
.pk-after-note {
  margin: clamp(12px, 1.4vw, 18px) 0 0;
  text-align: center;
  font-family: var(--font-ui);
  font-size: 0.85rem;
  color: var(--muted);
}

/* The featured middle card carries the theme accent instead of charcoal, at
   the client's request: the white glow and the animated white hairline are
   removed with it, and the CTA inverts to ivory-on-green because the green
   button would vanish on the green accent. */
.pk-cards .pk-hero:nth-child(2) {
  background: var(--gold);
  color: var(--ivory);
  border-color: transparent;
}
.pk-cards .pk-hero:nth-child(2)::after {
  background: none;
}
.pk-cards .pk-hero:nth-child(2)::before {
  animation: none;
  box-shadow: none;
}
.pk-cards .pk-hero:nth-child(2) .pk-cta,
.pk-cards .pk-hero:nth-child(2) .pk-cta:hover {
  background: var(--ivory);
  color: var(--gold);
}
.pk-cards .pk-hero:nth-child(2) .pk-badge--hero {
  color: var(--ivory);
  border-color: rgba(251, 248, 243, 0.34);
}
.pk-cards .pk-hero:nth-child(2) .pk-hero-icon {
  background: rgba(251, 248, 243, 0.1);
  color: var(--gold-soft);
}
.pk-cards .pk-hero:nth-child(2) .pk-hero-title h3 { color: var(--ivory); }
.pk-cards .pk-hero:nth-child(2) .pk-hero-for { color: rgba(251, 248, 243, 0.8); }
.pk-cards .pk-hero:nth-child(2) .pk-hero-for strong { color: var(--ivory); }
.pk-cards .pk-hero:nth-child(2) .pk-price { color: #FFFFFF; }
.pk-cards .pk-hero:nth-child(2) .pk-price-note { color: rgba(251, 248, 243, 0.72); }
.pk-cards .pk-hero:nth-child(2) .pk-fee-cap { color: rgba(251, 248, 243, 0.62); }
.pk-cards .pk-hero:nth-child(2) .pk-price-note .pk-fee-soft { color: rgba(251, 248, 243, 0.72); }
.pk-cards .pk-hero:nth-child(2) .pk-price-note .pk-fee-free { color: var(--gold-soft); }
.pk-cards .pk-hero:nth-child(2) .pk-includes { border-top-color: rgba(251, 248, 243, 0.18); }
.pk-cards .pk-hero:nth-child(2) .pk-list-label { color: rgba(251, 248, 243, 0.62); }
.pk-cards .pk-hero:nth-child(2) .pk-spec dt { color: rgba(251, 248, 243, 0.62); }
.pk-cards .pk-hero:nth-child(2) .pk-spec dd { color: rgba(251, 248, 243, 0.92); }
.pk-cards .pk-hero:nth-child(2) .pk-list li i { color: var(--gold-soft); }
.pk-cards .pk-hero:nth-child(2):hover {
  box-shadow: 0 30px 60px -18px rgba(34, 84, 76, 0.55);
}

/* ---------- Packages: the card foot, the wider grid, (equi.) (2026-10-27) ----------
   The booking button moved to the end of the card: order 4 puts it after the
   details block and margin-top: auto pins it to every card's own foot line,
   where the equal-height grid guarantees spare space. The grid breaks out of
   the section inset so the three cards use the page's full width at wide
   viewports; the breakout stays inside --section-inset at every size, so no
   viewport grows a horizontal strip. The amounts stay on one line each, the
   (equi.) marker steps down inside the amount, and the Plan-details label is
   retinted: it carried the dark-card ivory on the light cards, where it was
   ivory on pale yellow and effectively invisible. */
.pk-cards .pk-cta { order: 4; margin-top: auto; }
.pk-cards .pk-includes { padding-bottom: clamp(12px, 1.4vw, 18px); }
.pk-price .pk-fee-usd,
.pk-price .pk-fee-pkr { white-space: nowrap; }
.pk-hero .pk-list-label { color: rgba(32, 28, 22, 0.6); }
/* A tick on every feature line, as the reference has it. The icon rides
   beside the value as a flex item with its own gap, so it never touches the
   text and wraps with the first line; the label above its value gets room
   to read as a label. */
.pk-hero .pk-pair dt { margin-bottom: 6px; }
.pk-hero .pk-spec dd {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}
.pk-spec-tick {
  flex: 0 0 auto;
  color: var(--gold);
  font-size: 1em;
  line-height: 1.6;
  margin-top: 0.1em;
}
.pk-cards .pk-hero:nth-child(2) .pk-spec-tick { color: var(--gold-soft); }
/* One-line plan titles. The icon chip sits above the title so the title
   gets the card's full width, and the size is capped with a nowrap so the
   longest plan title holds a single line on every device; the phone step
   keeps the ratio. */
.pk-cards .pk-hero-title {
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
}
.pk-cards .pk-hero-title h3 {
  font-size: clamp(1.15rem, 1.65vw, 1.35rem);
  white-space: nowrap;
}
/* One line where there is room. Below 480px the longest plan title cannot fit
   the phone card, and nowrap became a min-content floor that made the grid
   track wider than its container (the card hung 5px past a 320px viewport). */
@media (max-width: 480px) {
  .pk-cards .pk-hero-title h3 { white-space: normal; }
}
/* The featured card's centered Best Choice tag, and its Option pill inverted
   to charcoal text on an ivory fill at the client's request: the ivory text
   it carried was hard to read over the plate. Both are scoped to .pk-cards so
   an older template copy is unaffected. */
.pk-cards .pk-best-choice {
  align-self: center;
  background: var(--ivory);
  border-color: transparent;
  color: var(--charcoal);
  font-weight: 700;
}
.pk-cards .pk-hero:nth-child(2) .pk-badge--hero {
  background: var(--ivory);
  border-color: transparent;
  color: var(--charcoal);
}
/* At one-column widths the block button stretched to the full card and read
   as an extra-wide strip; it is capped and centred there instead. The
   three-column layout keeps it spanning the card. */
@media (max-width: 1100px) {
  .pk-cards .pk-cta {
    width: min(100%, 360px);
    align-self: center;
  }
}
.pk-equi {
  font-size: 0.5em;
  font-weight: 600;
  letter-spacing: 0.02em;
  opacity: 0.7;
}
@media (min-width: 1101px) {
  .pk-cards {
    width: calc(100% + clamp(64px, 12vw, 200px));
    margin-inline: calc(clamp(32px, 6vw, 100px) * -1);
  }
}
