/*
Theme Name: Healing Drum
Theme URI: https://healingdrum.co.uk
Author: Healing Drum
Description: Warm parchment, antique gold and walnut theme for Healing Drum - sound healing drum courses, workshops and practitioner training from College of Sound Healing tutors. Includes a Courses post type, icon cards and four accent colour directions.
Version: 1.8.154
Update URI: false
Requires at least: 6.0
Tested up to: 7.0
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: healing-drum
Tags: education, custom-logo, custom-menu, featured-images, one-column, two-columns
*/

/* ---------------------------------------------------------------------------
   WHY "Update URI: false" IS IN THE HEADER ABOVE, and do not remove it

   This theme is not on wordpress.org, and its slug - healing-drum - is not
   reserved there. Nothing stops somebody publishing a theme under that slug
   tomorrow. If they did, WordPress's daily theme update check would match it
   by slug, and the moment their version number passed ours the Updates screen
   would offer it. One press of Update All would replace the whole theme with a
   stranger's, on a live site, silently.

   WordPress posts every installed theme's headers - including this one - to
   api.wordpress.org/themes/update-check/. A theme whose Update URI is anything
   other than a wordpress.org address is not offered an update from there, so
   the collision cannot reach us. Core reads the header for themes exactly as
   it does for plugins (wp-includes/update.php collects 'UpdateURI' into the
   posted theme list).

   The Coming Soon Wall plugin carries the same line for the same reason, and
   its slug is far likelier to be claimed. Checked 20 August 2026: neither
   healing-drum nor coming-soon-wall exists on wordpress.org today. That is
   luck, not protection, which is the point of the header (James, 20 Aug 2026).
--------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
   1. Palette & base  (from the Healing Drum brand kit)
--------------------------------------------------------------------------- */
:root{
  --hd-parchment:#EEE3C6;
  --hd-warm-sand:#E4CF9F;
  --hd-card:#FBF5E6;
  /* Darkened from #B0894F on 30 July 2026. The old gold measured 2.95:1 on the
     card and 2.51:1 on the parchment, which failed WCAG AA for text (4.5) and
     also failed the 3.0 wanted for focus rings and component borders. It was
     carrying the primary button label, link hover, the eyebrow, the strapline
     and :focus-visible, so this was a real failure and not a theoretical one.
     This value holds the original hue (35.9 deg) and saturation exactly and
     moves only the lightness: 5.31:1 on card, 4.52:1 on parchment. Going
     further, to AAA, lands on #5A4628, which is indistinguishable from
     --hd-walnut and stops reading as gold at all. */
  --hd-gold:#7D6138;
  /* Lightened from #C9AC77 on 30 July 2026. Used only on the walnut strip and
     the footer, both of which are a walnut to walnut-deep gradient. The old
     value measured 4.22:1 against walnut and 5.25:1 against walnut-deep, so it
     failed AA at one end of the gradient and passed at the other. This value
     holds the hue and saturation and lifts the lightness: 4.53:1 and 5.63:1.
     That is a thin margin over 4.5, so re-measure if it is ever nudged. */
  --hd-gold-soft:#CDB382;
  --hd-bronze:#8C6A38;
  --hd-walnut:#5C4327;
  --hd-walnut-deep:#4A3620;
  --hd-ink:#3B3226;
  --hd-ink-muted:#6E634E;
  --hd-line:rgba(107,78,46,.16);
  /* The edge on a badge pill. A tint rather than a named colour, so it reads
     whatever background an administrator picks in Settings - see .hd-badge.
     It is a variable so a dark palette can flip it to a white tint: black at
     12% is invisible against a dark page, which is exactly where a pill most
     needs its edge. Only the light value exists so far, so this is currently
     identical to the literal it replaced. */
  --hd-pill-edge:rgba(0,0,0,.12);
  /* The edge on a .tag chip. Its own variable rather than sharing
     --hd-pill-edge, because the chip's edge is a gold tint and the badge's is
     neutral black: the two were chosen to look different and still should.
     This only had to become a variable so the dark scheme could lift it off a
     dark background, where a gold tint at 30% all but disappears. */
  --hd-tag-edge:rgba(125,97,56,.3);
  /* Form-field borders: stronger than the hairline card/divider tone, so a
     resting field reads clearly against the parchment. */
  --hd-line-strong:rgba(107,78,46,.38);
  /* The message fold-out's panel. NOT --hd-card: the fold-out sits inside a
     card, so it needs a tint distinguishable from its parent in both
     palettes - a shade deeper than the card in light, a shade lifted off it
     in dark. */
  --hd-message-bg:#F6EEDA;
  /* Error text and borders. The admin blocks that predate this variable
     carry the same value as a literal; new rules use the variable so the
     dark palette can lift it. */
  --hd-error:#b32d2e;

  /* Kept identical to --hd-gold. If the two ever need to differ, check both
     against --hd-card and --hd-parchment before shipping it. */
  --hd-accent:#7D6138;
  --hd-accent-tint:#E4CF9F;

  /* Surfaces that are dark in BOTH themes, split out on 30 July 2026 so the
     dark palette could exist at all. --hd-walnut is text in four rules and a
     dark background in four others, so flipping it wholesale would have turned
     the walnut strip cream. These carry the background half of that job and do
     not flip; --hd-walnut keeps the text half and does. Values are identical to
     what those rules used before, so light mode renders byte for byte the same. */
  --hd-strip-from:#5C4327;
  --hd-strip-to:#4A3620;
  /* The text colour for anything sitting ON those dark surfaces. It does
     NOT flip, because the strip and the footer are dark in both themes.
     Anything there that used --hd-card as 'the light one' broke in dark,
     because --hd-card is a surface colour and flips to #3B3226. If you
     are adding a rule inside .hd-strip or .site-footer, this is the
     colour you want, not --hd-card and not --hd-ink. */
  --hd-strip-ink:#EEE3C6;
  /* The badge pill when Settings has not overridden it, and the icon sitting on
     the badge's light disc. Both stay dark whatever the theme, because the disc
     stays light and the pill colour is an administrator's choice, not ours. */
  --hd-badge-fallback:#5C4327;
  /* The Mark chip once a visitor has marked something. Was an undefined
     variable relying on its own fallback, so nothing could ever change it.
     The glyph on it is --hd-card, which flips, so the chip has to flip the
     other way: a dark green with cream on it in light, a light green with
     dark on it in dark. One rule, correct in both. */
  --hd-marked:#6B7A4F;

  /* Surfaces that were written as literals before there was a second palette to
     answer to, so they could not follow it. The header bar and the two hero
     gradients. Added 30 July 2026; light values are exactly what those rules
     held before.

     NOT here, and deliberately: the white discs behind badge artwork and the
     white membership chips. Those hold other people's logos, drawn for a light
     background, and a dark disc would make transparent artwork disappear. They
     stay white in both themes for the same reason --hd-badge-fallback does. */
  --hd-header-bg:rgba(238,227,198,.92);
  --hd-hero-from:#F6EDD6;
  --hd-hero-mid:#EADFBC;
  --hd-hero-to:#E3D6AE;
  --hd-hero-glow:rgba(251,245,230,.75);
  --hd-font:'Mulish',system-ui,-apple-system,'Segoe UI',sans-serif;

  /* Corner radii. Four steps, and every rounded corner on the site uses one of
     them, so softening or sharpening the whole site is four numbers here rather
     than thirty edits scattered through this file. Before this there were
     thirteen different values chosen in the moment: 2, 3, 4, 8, 10, 12, 14, 16,
     18, 20, 21 and 26px.

     Circles (50%) and the odd true pill (999px) are shapes rather than softened
     corners and deliberately do NOT use these.

     The admin cannot see these - a stylesheet in wp-admin has no access to the
     front end's :root - so assets/css/admin-members.css carries its own copy of
     the same four numbers. Change one, change the other. */
  --hd-radius-sm:3px;    /* focus rings, the smallest chips */
  --hd-radius-md:8px;    /* small controls, sub-menu items, tags */
  --hd-radius-lg:12px;   /* cards, panels, inputs, images */
  --hd-radius-pill:20px; /* controls meant to read as pills: buttons, search */
}
[data-accent="terracotta"]{--hd-accent:#B0663F;--hd-accent-tint:#E6C3A6;}
[data-accent="indigo"]    {--hd-accent:#4C577C;--hd-accent-tint:#B9C0D4;}
[data-accent="sage"]      {--hd-accent:#7C8A5E;--hd-accent-tint:#CDD5B8;}

/* ---------------------------------------------------------------------------
   1b. Dark palette  (James chose "walnut reversed", 30 July 2026)
--------------------------------------------------------------------------- */

/* The values live here once, so a change is made in one place. The two blocks
   below only ever map them onto the live variables. On a dark surface the
   accent has to go LIGHTER, not darker, which is why --hd-d-gold is close to
   the old pre-repair gold rather than the new one.

   Measured against this palette: body text 11.90:1, muted text 6.34:1, accent
   text 6.21:1, button label on the accent 7.51:1, focus ring 7.51:1. The worst
   figure here is better than the best figure the light theme manages. */
:root{
  --hd-d-page:#2E2417;
  --hd-d-card:#3B3226;
  --hd-d-sand:#5C4327;
  --hd-d-gold:#CDB382;
  --hd-d-gold-soft:#E4CF9F;
  --hd-d-bronze:#C9AC77;
  --hd-d-walnut:#E4CF9F;
  --hd-d-ink:#EEE3C6;
  --hd-d-ink-muted:#C4B79A;
  --hd-d-line:rgba(238,227,198,.16);
  --hd-d-line-strong:rgba(238,227,198,.34);
  --hd-d-pill-edge:rgba(255,255,255,.16);
  --hd-d-strip-from:#241C12;
  --hd-d-strip-to:#161009;
  --hd-d-header-bg:rgba(46,36,23,.92);
  --hd-d-hero-from:#3E3020;
  --hd-d-hero-mid:#34281A;
  --hd-d-hero-to:#251D12;
  /* A cream halo behind the drum rather than a cream blob: on a dark hero a
     low-alpha warm glow reads as light falling on the artwork. */
  --hd-d-hero-glow:rgba(228,207,159,.12);
  /* B of the two candidates (James, 30 July): 7.03:1 for the glyph on
     the chip, against 4.54 for the darker option. Pale enough to read
     as sage rather than green, which was the trade he took. */
  --hd-d-marked:#BBC6A7;
  --hd-d-tag-edge:rgba(238,227,198,.28);
  /* The message fold-out: a step up from --hd-d-card towards the sand, so the
     panel reads as its own surface inside a dark card. */
  --hd-d-message-bg:#46392A;
  /* Error red lifted for a dark surface, the same move the accent makes:
     5.6:1 against --hd-d-message-bg, where #b32d2e manages barely 2:1. */
  --hd-d-error:#E8A199;
}

/* Applied two ways, and the duplication is unavoidable in plain CSS.

   The media query is the automatic case: a device asking for dark gets dark
   with no cookie, no script and no choice to make. The :not() is what lets
   somebody who has explicitly chosen Light keep it on a device set to dark.

   The attribute selector is the explicit case. PHP writes data-hd-theme onto
   the html element from a cookie before anything is sent, so there is no flash
   and no inline script - see hd_display_html_attributes() in functions.php. */
@media (prefers-color-scheme:dark){
  :root:not([data-hd-theme="light"]){
    color-scheme:dark;
    --hd-parchment:var(--hd-d-page);
    --hd-card:var(--hd-d-card);
    --hd-warm-sand:var(--hd-d-sand);
    --hd-gold:var(--hd-d-gold);
    --hd-gold-soft:var(--hd-d-gold-soft);
    --hd-bronze:var(--hd-d-bronze);
    --hd-walnut:var(--hd-d-walnut);
    --hd-ink:var(--hd-d-ink);
    --hd-ink-muted:var(--hd-d-ink-muted);
    --hd-line:var(--hd-d-line);
    --hd-line-strong:var(--hd-d-line-strong);
    --hd-pill-edge:var(--hd-d-pill-edge);
    --hd-accent:var(--hd-d-gold);
    --hd-accent-tint:var(--hd-d-sand);
    --hd-strip-from:var(--hd-d-strip-from);
    --hd-strip-to:var(--hd-d-strip-to);
    --hd-header-bg:var(--hd-d-header-bg);
    --hd-hero-from:var(--hd-d-hero-from);
    --hd-hero-mid:var(--hd-d-hero-mid);
    --hd-hero-to:var(--hd-d-hero-to);
    --hd-hero-glow:var(--hd-d-hero-glow);
    --hd-marked:var(--hd-d-marked);
    --hd-tag-edge:var(--hd-d-tag-edge);
    --hd-message-bg:var(--hd-d-message-bg);
    --hd-error:var(--hd-d-error);
  }
}
:root[data-hd-theme="dark"]{
  color-scheme:dark;
  --hd-parchment:var(--hd-d-page);
  --hd-card:var(--hd-d-card);
  --hd-warm-sand:var(--hd-d-sand);
  --hd-gold:var(--hd-d-gold);
  --hd-gold-soft:var(--hd-d-gold-soft);
  --hd-bronze:var(--hd-d-bronze);
  --hd-walnut:var(--hd-d-walnut);
  --hd-ink:var(--hd-d-ink);
  --hd-ink-muted:var(--hd-d-ink-muted);
  --hd-line:var(--hd-d-line);
  --hd-line-strong:var(--hd-d-line-strong);
  --hd-pill-edge:var(--hd-d-pill-edge);
  --hd-accent:var(--hd-d-gold);
  --hd-accent-tint:var(--hd-d-sand);
  --hd-strip-from:var(--hd-d-strip-from);
  --hd-strip-to:var(--hd-d-strip-to);
  --hd-header-bg:var(--hd-d-header-bg);
  --hd-hero-from:var(--hd-d-hero-from);
  --hd-hero-mid:var(--hd-d-hero-mid);
  --hd-hero-to:var(--hd-d-hero-to);
  --hd-hero-glow:var(--hd-d-hero-glow);
  --hd-marked:var(--hd-d-marked);
  --hd-tag-edge:var(--hd-d-tag-edge);
  --hd-message-bg:var(--hd-d-message-bg);
  --hd-error:var(--hd-d-error);
}

/* Movement. The media query is the automatic case again; the attribute is the
   override for somebody whose device does not carry the setting, or who wants
   it here and not everywhere. Kept to transitions, animations and smooth
   scrolling: this is about vestibular comfort, not about removing feedback. */
@media (prefers-reduced-motion:reduce){
  html:not([data-hd-motion="full"]){scroll-behavior:auto;}
  :root:not([data-hd-motion="full"]) *,
  :root:not([data-hd-motion="full"]) *::before,
  :root:not([data-hd-motion="full"]) *::after{
    animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important;scroll-behavior:auto !important;
  }
}
:root[data-hd-motion="reduce"]{scroll-behavior:auto;}
:root[data-hd-motion="reduce"] *,
:root[data-hd-motion="reduce"] *::before,
:root[data-hd-motion="reduce"] *::after{
  animation-duration:.001ms !important;animation-iteration-count:1 !important;
  transition-duration:.001ms !important;scroll-behavior:auto !important;
}

*,*::before,*::after{box-sizing:border-box;}
html{scroll-behavior:smooth;}
body{
  margin:0;
  background:var(--hd-parchment);
  color:var(--hd-ink);
  font-family:var(--hd-font);
  font-size:16px;line-height:1.65;
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%;height:auto;}
h1,h2,h3,h4{font-weight:700;letter-spacing:-.01em;line-height:1.15;color:var(--hd-ink);margin:0 0 .45em;}
h1{font-size:clamp(2rem,4.5vw,3.1rem);}
h2{font-size:clamp(1.5rem,3vw,2.1rem);}
h3{font-size:1.2rem;}
p{color:var(--hd-ink-muted);margin:0 0 1.1em;}
a{color:var(--hd-bronze);text-decoration:none;transition:color .15s ease;}
a:hover{color:var(--hd-accent);}
blockquote{
  margin:1.6em 0;padding:.4em 0 .4em 1.4em;
  border-left:3px solid var(--hd-gold);color:var(--hd-ink-muted);font-style:italic;
}
hr{border:0;border-top:1px solid var(--hd-line);margin:2.5em 0;}
:focus-visible{outline:2px solid var(--hd-accent);outline-offset:3px;border-radius:var(--hd-radius-sm);}

.hd-wrap{max-width:1120px;margin:0 auto;padding:0 24px;}

/* Helpers */
.hd-eyebrow{font-weight:600;font-size:.72rem;letter-spacing:.22em;text-transform:uppercase;color:var(--hd-accent);margin-bottom:14px;}
.hd-card{background:var(--hd-card);border:1px solid var(--hd-line);border-radius:var(--hd-radius-lg);}
.hd-icon{color:var(--hd-accent);}
.hd-icon-chip{
  display:inline-flex;align-items:center;justify-content:center;
  width:58px;height:58px;border-radius:50%;
  background:var(--hd-card);border:1px solid rgba(125,97,56,.35);
  color:var(--hd-gold);font-size:27px;
}
/* Form controls get the site font too - browsers give inputs their own default
   and never inherit, so without this the contact form's labels and button fall
   back to the system font while everything around them is Mulish. */
input,textarea,select,button{font-family:inherit;}

.hd-rule{display:flex;align-items:center;gap:3px;margin:20px 0;}
.hd-rule span{width:56px;height:1px;background:var(--hd-gold);}
/* In the front-page hero the rule runs the full width of the text column,
   matching the full-width rule above "Courses with X" on tutor profiles.
   The short fixed-width version remains for small centred ornaments (404). */
.hd-hero .hd-rule span{flex:1;width:auto;}
.hd-rule i{color:var(--hd-gold);font-size:20px;}
.hd-rule.is-center{justify-content:center;}

/* Buttons */
.hd-btn,
.wp-block-button__link,
button[type=submit],input[type=submit]{
  display:inline-block;font-family:var(--hd-font);font-weight:700;font-size:.8rem;
  letter-spacing:.06em;text-transform:uppercase;color:var(--hd-card);
  background:var(--hd-accent);padding:13px 24px;border-radius:var(--hd-radius-pill);border:0;cursor:pointer;
  transition:filter .15s ease,transform .15s ease;
}
.hd-btn:hover,.wp-block-button__link:hover,button[type=submit]:hover,input[type=submit]:hover{
  filter:brightness(.94);color:var(--hd-card);transform:translateY(-1px);
}
.hd-btn.is-ghost{
  background:transparent;color:var(--hd-bronze);
  border:1px solid var(--hd-gold);
}
.hd-btn.is-ghost:hover{background:var(--hd-card);color:var(--hd-walnut);}
.hd-btn i{font-size:1.05rem;vertical-align:-3px;}
.hd-btn i.lead{margin-right:2px;}
.hd-btn i.end{margin-left:2px;}
.hd-eyebrow i{font-size:1.35em;vertical-align:-3px;margin-right:7px;}

/* ---------------------------------------------------------------------------
   2. Header & navigation
--------------------------------------------------------------------------- */
.site-header{
  position:sticky;top:0;z-index:40;
  background:var(--hd-header-bg);
  backdrop-filter:blur(8px);
  border-bottom:1px solid var(--hd-line);
}
/* The admin bar against a sticky header. Signed-in users only; a visitor never
   sees one. WordPress fixes the bar at 32px, switches it to 46px below 782px,
   and below 600px makes it position:absolute so it scrolls away with the page.
   Without these the header slid underneath it on every scroll. The third rule
   is not redundant: at top:46px once the bar has scrolled off below 600px, the
   header would stick 46px down the screen with nothing above it. */
body.admin-bar .site-header{top:32px;}
@media screen and (max-width:782px){body.admin-bar .site-header{top:46px;}}
@media screen and (max-width:600px){body.admin-bar .site-header{top:0;}}

/* Where anchor navigation lands (James, 7 August 2026). The header is sticky,
   so a bare jump puts the target's top edge underneath it; scroll-padding on
   the document makes every scroll-into-view - anchor links, the research
   page's contents list, the skip link, focus scrolling - stop short of the
   header instead. 92 is the 78px min-height plus the 1px rule plus air. The
   admin-bar tiers mirror the three rules above exactly; they have to sit on
   html because scroll-padding belongs to the scrolling element, so :has()
   carries the body class up. A browser without :has() (pre-2023) simply
   lands signed-in staff 32px higher - visitors never carry the bar at all. */
html{scroll-padding-top:92px;}
html:has(body.admin-bar){scroll-padding-top:124px;}
@media screen and (max-width:782px){html:has(body.admin-bar){scroll-padding-top:138px;}}
@media screen and (max-width:600px){html:has(body.admin-bar){scroll-padding-top:92px;}}
.site-header .hd-wrap{display:flex;align-items:center;gap:24px;min-height:78px;}
.site-branding{display:flex;align-items:center;gap:14px;}
.site-branding img{display:block;height:52px;width:auto;}
.site-branding .custom-logo{height:52px;width:auto;}
.site-title-text{display:flex;flex-direction:column;line-height:1.1;}
.site-title-text .name{font-weight:700;font-size:1.25rem;letter-spacing:-.015em;color:var(--hd-ink);}
.site-title-text .strap{font-weight:600;font-size:.58rem;letter-spacing:.2em;text-transform:uppercase;color:var(--hd-accent);margin-top:4px;}

.main-nav{margin-left:auto;}
.main-nav ul{list-style:none;display:flex;gap:6px;margin:0;padding:0;align-items:center;}
.main-nav li{position:relative;}
.main-nav a{
  /* Tightened from 10px 14px: the hover box read as a button rather than a
     highlight (James, 29 July). Still comfortably over the 24px the link needs
     to stay easy to hit with a mouse. */
  display:block;padding:7px 12px;border-radius:var(--hd-radius-pill);
  font-weight:600;font-size:.86rem;color:var(--hd-ink);
}
.main-nav a:hover,
.main-nav .current-menu-item > a,
.main-nav .current_page_item > a{color:var(--hd-bronze);background:var(--hd-card);}
.main-nav .sub-menu{
  display:none;position:absolute;top:100%;left:0;min-width:210px;
  background:var(--hd-card);border:1px solid var(--hd-line);border-radius:var(--hd-radius-lg);
  padding:8px;box-shadow:0 14px 34px rgba(59,50,38,.14);
}
.main-nav li:hover > .sub-menu,
.main-nav li:focus-within > .sub-menu{display:block;}
.main-nav .sub-menu a{border-radius:var(--hd-radius-md);}

/* Caret on any parent item, so a dropdown announces itself before it is
   hovered. \e136 is ph-caret-down from the theme's own Phosphor Light font,
   already loaded on every page, so this costs no extra request. It flips to
   point up while the dropdown is open. The global prefers-reduced-motion rule
   further down already cancels the transition. */
.main-nav .menu-item-has-children > a::after{
  content:"\e136";font-family:"Phosphor-Light";
  display:inline-block;font-size:.72em;line-height:1;
  margin-left:6px;vertical-align:middle;
  transition:transform .18s ease;
}
.main-nav .menu-item-has-children:hover > a::after,
.main-nav .menu-item-has-children:focus-within > a::after{transform:rotate(180deg);}

/* margin-left:auto is back here from .hd-theme-toggle: the toggle now sits
   after the nav, so at the collapsed widths it is the hamburger that leads the
   right-hand group. On a wide screen this button is display:none and the
   margin does nothing; .main-nav's own auto margin does the pushing there. */
.nav-toggle{
  display:none;margin-left:auto;background:none;border:1px solid var(--hd-line);
  border-radius:var(--hd-radius-md);padding:10px 12px;color:var(--hd-walnut);font-size:22px;line-height:1;cursor:pointer;
}

/* Light/dark button, last in the header row at every width - after Contact Us
   on a wide screen, after the hamburger once the nav has collapsed. Sized down
   to sit level with the menu items beside it (about 30px tall against their
   28px), still over the 24px minimum target size.

   Both icons are in the markup and CSS picks one, so the button is correct on
   first paint with no script. It is printed hidden and revealed by theme.js:
   without script it could not store a choice, and the automatic behaviour
   already follows the device, so there is nothing to offer.

   The [hidden] rule is not redundant, and it is visibility on purpose (James,
   7 August 2026). The display rule above beats the hidden attribute - the trap
   the Mark buttons hit, see .hd-btn[hidden] further down - so without a rule
   here the button would never hide at all. But hiding it with display:none
   laid the header row out WITHOUT the button, and the whole menu jumped left
   when the script revealed it after first paint. visibility keeps the box in
   the row from the start, invisible, unclickable and out of the tab order, so
   the reveal changes a single pixel of nothing. The price is that with script
   off, an invisible button-sized gap sits after the last menu item. */
.hd-theme-toggle{
  display:inline-flex;align-items:center;justify-content:center;
  /* The header row's flex gap is 24px for every pair and cannot be set per
     pair, so the negative margin nets this one down to 12px - the button was
     sitting too far off Contact Us (and off the hamburger when collapsed). */
  margin-left:-12px;
  background:none;border:1px solid var(--hd-line);
  border-radius:var(--hd-radius-md);padding:6px;color:var(--hd-walnut);
  font-size:16px;line-height:1;cursor:pointer;
}
.hd-theme-toggle[hidden]{visibility:hidden;}
.hd-theme-toggle:hover{border-color:var(--hd-gold);color:var(--hd-gold);}
/* Three states. data-when is the state the visitor is in; the icon inside it is
   where pressing takes them - moon while light, half-circle while dark, sun
   while matching the device. Because this keys off the CHOICE and not the
   resolved colour there is no prefers-color-scheme branch here at all: that
   media query was only ever needed by the old two-icon version, which had to
   work out what the device was doing before it knew which icon to draw. An
   absent attribute means "match my device", which is how that state is stored -
   no attribute and no cookie. */
.hd-theme-toggle i{display:none;}
.hd-theme-toggle i[data-when="auto"]{display:block;}
:root[data-hd-theme="light"] .hd-theme-toggle i[data-when="auto"]{display:none;}
:root[data-hd-theme="light"] .hd-theme-toggle i[data-when="light"]{display:block;}
:root[data-hd-theme="dark"] .hd-theme-toggle i[data-when="auto"]{display:none;}
:root[data-hd-theme="dark"] .hd-theme-toggle i[data-when="dark"]{display:block;}
@media (max-width:820px){
  .nav-toggle{display:inline-flex;}
  .main-nav{
    display:none;position:absolute;top:100%;left:0;right:0;margin:0;
    background:var(--hd-card);border-bottom:1px solid var(--hd-line);
    box-shadow:0 20px 40px rgba(59,50,38,.15);
  }
  .main-nav.is-open{display:block;}
  .main-nav ul{flex-direction:column;align-items:stretch;gap:0;padding:12px 18px;}
  .main-nav a{padding:12px 10px;border-radius:var(--hd-radius-md);}
  .main-nav .sub-menu{position:static;box-shadow:none;border:0;padding:0 0 0 18px;}

  /* Sub-menus fold away in the burger and open on a tap, so the list stays
     short as the menu grows. The hover and focus-within rules further up are
     cancelled here on purpose: a tap can leave a lingering hover on a touch
     screen, which would spring a sub-menu open behind the toggle's back. */
  .main-nav .sub-menu,
  .main-nav li:hover > .sub-menu,
  .main-nav li:focus-within > .sub-menu{display:none;}
  .main-nav .menu-item-has-children.is-expanded > .sub-menu{display:block;}

  /* For the same reason the caret follows the toggle here rather than the
     pointer. The reset comes first so the open state overrides it, since the
     two selectors carry the same weight. */
  .main-nav .menu-item-has-children:hover > a::after,
  .main-nav .menu-item-has-children:focus-within > a::after{transform:none;}
  .main-nav .menu-item-has-children.is-expanded > a::after{transform:rotate(180deg);}
}

/* ---------------------------------------------------------------------------
   3. Hero (front page)
--------------------------------------------------------------------------- */
.hd-hero{
  position:relative;overflow:hidden;
  background:radial-gradient(120% 90% at 50% 0%, var(--hd-hero-from) 0%, var(--hd-hero-mid) 62%, var(--hd-hero-to) 100%);
  border-bottom:1px solid var(--hd-line);
}
.hd-hero .hd-wrap{
  position:relative;display:grid;grid-template-columns:1.1fr .9fr;gap:40px;
  align-items:center;padding-top:72px;padding-bottom:72px;
}
.hd-hero h1{margin-bottom:.35em;}
.hd-hero .lead{font-size:1.08rem;max-width:34em;}
.hd-hero .actions{display:flex;flex-wrap:wrap;gap:14px;margin-top:26px;}
.hd-hero .art{position:relative;text-align:center;}
.hd-hero .art img{max-width:420px;width:100%;filter:drop-shadow(0 24px 40px rgba(92,67,39,.28));}
.hd-hero .art::before{
  content:"";position:absolute;inset:8% 10%;border-radius:50%;
  background:radial-gradient(circle, var(--hd-hero-glow) 0%, transparent 70%);
  z-index:-1;
}
@media (max-width:820px){
  /* Left aligned, not centred. The front page used to centre its heading, rule,
     lead and buttons on a phone while every other page kept them left, so the
     home screen read as a different site from the one behind it. The drum keeps
     its own centring, which lives on .art and is unaffected by this. */
  .hd-hero .hd-wrap{grid-template-columns:1fr;padding-top:52px;padding-bottom:52px;}
  /* No size rule for the drum here. .hd-hero.is-compact .art img sets 260px
     further down the file, outside any media query and at higher specificity,
     so anything written here would never win. 260px is comfortable on a phone,
     so the drum simply keeps that size at every width. */
  /* The compact hero's own small-screen rules are further down the file too,
     directly after the rules they have to beat, and for the same reason. */
}

/* ---------------------------------------------------------------------------
   4. Sections & cards
--------------------------------------------------------------------------- */
.hd-section{padding:72px 0;}
.hd-section.is-sand{background:var(--hd-warm-sand);border-block:1px solid var(--hd-line);}
.hd-section-head{max-width:640px;margin-bottom:40px;}
.hd-section-head.is-center{margin-inline:auto;text-align:center;}

.hd-grid{display:grid;gap:22px;grid-template-columns:repeat(3,1fr);}
@media (max-width:900px){.hd-grid{grid-template-columns:repeat(2,1fr);}}
@media (max-width:600px){.hd-grid{grid-template-columns:1fr;}}

/* "See All Courses" beneath the front-page showcase grid. */
.hd-see-all{text-align:center;margin:38px 0 0;}

.hd-tile{
  padding:30px 26px;display:flex;flex-direction:column;gap:14px;
  transition:transform .18s ease,box-shadow .18s ease;
}
.hd-tile:hover{transform:translateY(-4px);box-shadow:0 18px 36px rgba(92,67,39,.14);}
.hd-tile h3{margin:0;}
.hd-tile p{margin:0;font-size:.95rem;}

/* Course cards */
.course-card{overflow:hidden;padding:0;display:flex;flex-direction:column;}
.course-card .thumb{aspect-ratio:16/10;overflow:hidden;background:var(--hd-warm-sand);display:block;}
.course-card .thumb img{width:100%;height:100%;object-fit:cover;transition:transform .3s ease;}
.course-card:hover .thumb img{transform:scale(1.04);}
.course-card .thumb.is-placeholder{display:flex;align-items:center;justify-content:center;}
.course-card .thumb.is-placeholder img{width:44%;height:auto;object-fit:contain;opacity:.85;}
.course-card .body{padding:24px 24px 26px;display:flex;flex-direction:column;gap:10px;flex:1;}
.course-card h3{margin:0;font-size:1.15rem;}
.course-card h3 a{color:var(--hd-ink);}
.course-card h3 a:hover{color:var(--hd-bronze);}
/* The description block is a fixed three lines on every card, trimmed with an
   ellipsis if longer and left blank if there is nothing to say. Without it the
   row stretches to its wordiest card and the quiet ones gain a hole in the
   middle, which reads as a fault rather than as a short listing. */
.course-card .excerpt{
  font-size:.93rem;margin:0;line-height:1.55;min-height:4.65em;
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;
}
.course-meta{display:flex;flex-direction:column;gap:6px;margin:4px 0 0;padding:0;list-style:none;font-size:.88rem;color:var(--hd-ink-muted);}
.course-meta i{color:var(--hd-gold);font-size:17px;vertical-align:-3px;margin-right:8px;}
/* On the cards, when and where carry more weight than what it costs: with most
   titles reading "Sound Healing with the Drum", the dates and the venue are what
   tell two courses apart. Scoped to the card so a course page is unaffected. */
.course-card .course-meta li.when,
.course-card .course-meta li.where{font-weight:600;color:var(--hd-ink);}

/* Card type and tutor. Nearly every practitioner training shares the diploma's
   title, so the card leads with what actually differs: which type of course it
   is, then who is teaching it. The negative margin pulls the eyebrow up against
   its title, against the 10px flex gap the card body sets. */
.card-type{
  margin:0 0 -4px;font-weight:700;font-size:.7rem;letter-spacing:.16em;
  text-transform:uppercase;color:var(--hd-accent);
}
.card-tutor{
  margin:0;display:flex;align-items:center;gap:8px;
  font-weight:600;font-size:.95rem;color:var(--hd-ink);
}
.card-tutor i{color:var(--hd-gold);font-size:17px;}
/* margin-top:auto pins the button to the foot of the card, so buttons line up
   across a row and a sparse listing does not leave a void under itself. The
   tutor cards have always done this; the course cards had not. */
.course-card .hd-btn{align-self:flex-start;margin-top:auto;}

/* Compact hero variant (front page above the directory) */
/* Top-aligned, not centred: centring the copy against the art column means any
   change to the drum's size silently moves the text. Top alignment plus the
   same 54px padding as .page-hero pins the eyebrow to the exact height it has
   on every other page. */
.hd-hero.is-compact .hd-wrap{align-items:start;padding-top:54px;padding-bottom:52px;}
.hd-hero.is-compact .art{text-align:right;}
.hd-hero.is-compact .art img{max-width:260px;}
/* The glow follows the drum: a fixed circle centred behind the 260px image at
   the column's right edge, instead of filling the whole (now mostly empty)
   column. right:-20px puts its centre on the drum's centre. */
.hd-hero.is-compact .art::before{
  inset:auto;top:50%;right:-20px;width:300px;height:300px;
  transform:translateY(-50%);
}
/* Single centred column on small screens: the right-aligned drum re-centres and
   the glow returns to its column-filling default behind it.
   These have to live here rather than in the 820px block further up the file.
   The selectors are identical to the two directly above, so they tie on
   specificity and source order decides it. A media query adds none. Written up
   there they lost, and the drum kept its desktop right alignment on a phone. */
@media (max-width:820px){
  .hd-hero.is-compact .art{text-align:center;}
  .hd-hero.is-compact .art::before{
    inset:8% 10%;top:auto;right:auto;width:auto;height:auto;transform:none;
  }
}

/* ---------------------------------------------------------------------------
   Directory: filter bar + tutor grid
--------------------------------------------------------------------------- */
/* Sized to keep every control on one line at the 1072px content width: the five
   pills plus the Clear pill measure 1020px, leaving 52px of slack. Anything
   added here needs that budget checking again, or the row wraps. Below 1120px
   the wrap is intended - there is no room to do anything else. */
.directory-filters{
  display:flex;flex-wrap:wrap;gap:8px;align-items:center;justify-content:center;
  margin:0 0 12px;
}
.directory-filters label{
  display:inline-flex;align-items:center;gap:7px;
  background:var(--hd-card);border:1px solid var(--hd-line);border-radius:var(--hd-radius-pill);
  padding:4px 8px 4px 12px;
}
.directory-filters label i{color:var(--hd-gold);font-size:16px;}
.directory-filters select{
  border:0;background:transparent;font-family:var(--hd-font);font-weight:600;
  font-size:.82rem;color:var(--hd-ink);padding:6px 2px;cursor:pointer;max-width:160px;
}
.directory-filters select:focus{outline:none;}
.directory-filters input[type=text]{
  border:0;background:transparent;font-family:var(--hd-font);font-weight:600;
  font-size:.82rem;color:var(--hd-ink);padding:6px 2px;width:104px;
}
.directory-filters #filter-search{width:140px;}
.directory-filters input[type=text]:focus{outline:none;box-shadow:none;}
.directory-filters .hd-btn{padding:8px 13px;font-size:.78rem;}

/* Orientation copy under the directory grids, below the listings and separated
   by a rule rather than competing with them.
   Set in two columns so the block fills the width of the grid above it while
   each line stays a readable length. A single full-width column would run to
   about 110 characters a line, which is roughly half as easy to read as the 60
   to 70 a column gives here. Columns collapse to one below 820px, where there is
   no longer width to divide. */
.directory-intro{border-top:1px solid var(--hd-line);margin-top:56px;padding-top:40px;}
.directory-intro h2{font-size:1.3rem;}
.directory-intro .cols{columns:2;column-gap:56px;}
.directory-intro p{margin-top:0;break-inside:avoid;}
/* The block before its wording has been set up. Only an administrator ever sees
   this, so it is deliberately plain and obviously not the site's own writing. */
.directory-intro.is-setup{border-top-style:dashed;}
.directory-intro.is-setup h2{color:var(--hd-ink-muted);}
.directory-intro.is-setup p{max-width:66ch;margin-bottom:1.1em;}

/* The worked-out line under a region's standfirst: how many tutors, and the
   towns their courses are in. Facts, so it is set quieter than the writing. */
/* No negative top margin. It was pulling this line up against the standfirst
   with almost nothing between them; the paragraph above already carries its own
   bottom margin, which is the same gap every other stacked paragraph gets. */
.hd-region-facts{display:flex;align-items:center;gap:8px;margin:0;font-size:.92rem;color:var(--hd-ink-muted);}
.hd-region-facts i{color:var(--hd-accent);font-size:1.15em;}
@media (max-width:820px){
  .directory-intro .cols{columns:1;}
  .directory-intro{margin-top:40px;padding-top:30px;}
}

/* Feedback, not controls. Kept out of the filter row so that the results count
   or the "nearest to" note appearing can never push the controls onto a second
   line, and reserving a line's height so the grid does not jump when they do. */
.directory-status{
  display:flex;flex-wrap:wrap;justify-content:center;align-items:center;gap:14px;
  margin:0 0 26px;min-height:1.3em;
}
.postcode-msg{font-size:.85rem;font-weight:600;color:#B0663F;}
.postcode-msg.is-ok{color:var(--hd-bronze);}
.course-card .distance{
  margin:0;font-size:.85rem;font-weight:700;color:var(--hd-bronze);
}
.course-card .distance::before{content:"\2192";margin-right:6px;color:var(--hd-gold);}
.directory-count{font-size:.85rem;color:var(--hd-ink-muted);}
.directory-empty{text-align:center;margin:40px 0;color:var(--hd-ink-muted);}

/* Mark: the visitor's own shortlist, kept in their browser. Filled green when on
   rather than a filled glyph, because the theme ships Phosphor Light only and
   that weight has no solid bookmark in it - the chip carries the fill instead. */
.tutor-card,.course-card{position:relative;}
.hd-mark{
  position:absolute;top:10px;right:10px;z-index:2;
  display:inline-flex;align-items:center;justify-content:center;
  /* 28 round a 20px mark. It went 34, then 28, then 24, and 24 was too tight
     sitting over a photograph - the chip needs enough of itself to read against
     a busy image (James, 30 July). The smaller treatment is kept for the one
     beside a heading, where it sits on flat parchment instead. */
  width:28px;height:28px;padding:0;
  border:1px solid var(--hd-line);border-radius:var(--hd-radius-md);
  background:var(--hd-card);color:var(--hd-bronze);
  font-size:20px;line-height:1;cursor:pointer;
  transition:background .15s ease,color .15s ease,border-color .15s ease;
}
.hd-mark:hover{border-color:var(--hd-gold);color:var(--hd-walnut);}
.hd-mark[aria-pressed="true"]{
  background:var(--hd-marked,#6B7A4F);border-color:var(--hd-marked,#6B7A4F);
  color:var(--hd-card);
}
/* On a profile or a course page it sits beside the heading, not over a corner.

   BESIDE, and that is now literal: the Mark and the share row are siblings of
   the h1 rather than children of it. Inside, their screen-reader labels became
   part of the heading's own text content (AUDIT-2026-08-02 M1). The row is a
   flex container so the result looks exactly as it did.

   Beside a heading, on flat parchment, the chip can be tight to the glyph: 24
   round a 20px mark. Over a photograph it needs more of itself to read, which
   is why the card version above stays at 28. */
.hd-title-row{
  display:flex;align-items:center;flex-wrap:wrap;gap:14px;
}
/* Zeroed here rather than relying on the hero's own rule: a stray margin on a
   flex child offsets it against the controls beside it. */
.hd-title-row h1{margin:0;}
.hd-title-actions{
  display:inline-flex;align-items:center;gap:4px;
}
.hd-title-row .hd-mark{
  position:static;
  width:24px;height:24px;font-size:20px;
}
/* The share row's own left margin was spacing it off the Mark inside the
   heading. The flex gap does that now, so it would only double up. */
.hd-title-actions .hd-share{margin-left:0;}

/* Share: the row of plain share links beside the Mark chip on a hero. The
   same 24px chip treatment as the Mark beside a heading, so the cluster
   reads as one family. The copy and native buttons render [hidden] until
   theme.js proves the browser can do them - and [hidden] needs its own rule
   here because the chip styling below sets display. */
.hd-share{display:inline-flex;gap:4px;vertical-align:middle;margin-left:10px;}
.hd-share [hidden]{display:none;}
.hd-share a,.hd-share button{
  display:inline-flex;align-items:center;justify-content:center;
  width:24px;height:24px;padding:0;
  border:1px solid var(--hd-line);border-radius:var(--hd-radius-md);
  background:var(--hd-card);color:var(--hd-bronze);
  font-size:17px;line-height:1;cursor:pointer;
  transition:background .15s ease,color .15s ease,border-color .15s ease;
}
.hd-share a:hover,.hd-share button:hover{border-color:var(--hd-gold);color:var(--hd-walnut);}
/* The copied state borrows the Mark chip's green: a quiet tick, then back. */
.hd-share button.is-copied{
  background:var(--hd-marked,#6B7A4F);border-color:var(--hd-marked,#6B7A4F);
  color:var(--hd-card);
}
.hd-marked-filter{cursor:pointer;}
.directory-grid .is-hidden{display:none;}
/* Held back by the "Show more" cap rather than by a filter. A separate class
   from .is-hidden on purpose: a card can be filtered out, capped, both or
   neither, and theme.js needs to tell those apart to count what is behind the
   button.

   Scoped to .hd-grid, not .directory-grid: the region pages and the "Courses
   with X" block on a profile are capped too and are plain .hd-grid. */
.hd-grid .is-capped{display:none;}
.directory-more{margin:26px 0 0;text-align:center;}
/* The hidden attribute is a browser-stylesheet rule, and ANY author rule setting
   display beats it. .hd-btn sets display:inline-block, so hidden on one of these
   did nothing at all and the button sat there with nothing behind it (James, 29
   July). Setting hidden in JavaScript looked like it worked, because the
   property really was true - it was only ever the rendering that ignored it.

   Covers Clear in the filter bar as well, which is the same markup and had the
   same fault from the day it was written. */
.hd-btn[hidden],
.directory-more button[hidden]{display:none;}

/* Default avatar (no photo yet): gold Phosphor user icon on warm sand */
.avatar-default{
  display:flex;align-items:center;justify-content:center;
  width:100%;height:100%;background:var(--hd-warm-sand);color:var(--hd-gold);
}
.tutor-card .photo .avatar-default i{font-size:110px;}
.tutor-profile .portrait .avatar-default{aspect-ratio:1/1;}
.tutor-profile .portrait .avatar-default i{font-size:130px;}
.tutor-bio .pic .avatar-default{width:150px;height:150px;border-radius:50%;}
.tutor-bio .pic .avatar-default i{font-size:70px;}

.tutor-card{overflow:hidden;padding:0;display:flex;flex-direction:column;}
.tutor-card .photo{aspect-ratio:1/1;overflow:hidden;background:var(--hd-warm-sand);display:block;}
.tutor-card .photo img{width:100%;height:100%;object-fit:cover;transition:transform .3s ease;}
.tutor-card:hover .photo img{transform:scale(1.04);}
.tutor-card .body{padding:22px 24px 26px;display:flex;flex-direction:column;gap:9px;flex:1;}
.tutor-card h3{margin:0;font-size:1.18rem;}
.tutor-card h3 a{color:var(--hd-ink);}
.tutor-card h3 a:hover{color:var(--hd-bronze);}
.tutor-card .loc{margin:0;font-size:.88rem;color:var(--hd-ink-muted);}
.tutor-card .loc i{color:var(--hd-gold);font-size:16px;vertical-align:-2px;margin-right:7px;}
.tutor-card .excerpt{
  font-size:.92rem;margin:0;line-height:1.55;min-height:3.1em;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.tutor-card .hd-btn{align-self:flex-start;margin-top:auto;}

.tags{display:flex;flex-wrap:wrap;gap:7px;}
.tag{
  display:inline-flex;align-items:center;gap:6px;
  font-size:.68rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:var(--hd-bronze);background:var(--hd-accent-tint);
  border:1px solid var(--hd-tag-edge);border-radius:var(--hd-radius-md);padding:4px 11px;
}
.tag i{font-size:1.25em;}

/* The region chip: the one .tag that is a link. Beside the town on course and
   profile pages, to the region landing page, so the region hub is reachable
   from the pages visitors land on and not only the footer (SEO-2026-08-27 M3).
   The hover is its own rule because the plain a:hover selector is the more
   specific one against .tag, and would turn the chip accent instead of gold. */
a.tag:hover,a.tag:focus-visible{color:var(--hd-gold);}
.page-hero .sub .hd-region-chip{vertical-align:middle;margin-left:4px;}
.course-details .hd-region-chip{margin-top:6px;}

/* Tutor badge. Filled and fully rounded where the .tag chips above are tinted
   and squared off, because the two are answering different questions: a chip
   says what somebody teaches, a badge says who they are. Two signals of
   difference rather than one, so it does not rely on colour alone. */
.hd-badges{display:flex;flex-wrap:wrap;gap:7px;margin:0 0 10px;}
.hd-badge{
  display:inline-flex;align-items:center;gap:6px;
  font-size:.68rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:var(--hd-pill-tutor-text,var(--hd-card));
  background:var(--hd-pill-tutor-bg,var(--hd-badge-fallback));
  /* Neutral rather than a named colour, so the edge still reads whether the
     background chosen in Settings is dark or light. Moved to --hd-pill-edge on
     30 July 2026 so a dark palette can flip the tint; the value is unchanged. */
  border:1px solid var(--hd-pill-edge);border-radius:999px;
  /* Left padding matches the VERTICAL padding, not the right.
     The pill's height is the badge plus this padding twice, so the centre of its
     rounded end sits exactly that far in from the badge's own edge - which means
     an equal left padding puts the disc concentric with the curve, evenly spaced
     all the way round it. Matching the right-hand 11px instead left the disc
     adrift of the end it is meant to sit inside.

     2px, down from 4: at an 18px mark that takes the pill from 28px tall to 24,
     which is the floor before the disc and the text stop being what sets the
     height and the line-height has to be tightened too (James, 30 July).
     If these two ever diverge the disc goes off-centre again. */
  padding:2px 9px 2px 2px;
}
/* The mark sits on a light disc rather than straight on the walnut, so artwork
   with transparency or dark linework reads instead of disappearing into the
   pill. Icon and image share the shape and the size, so a badge looks the same
   before and after its artwork arrives.

   Sized from a variable set in Settings, and by CSS rather than by an image
   size, so artwork uploaded before today needs no thumbnail regenerating. */
.hd-badge i,
.hd-badge img{
  width:var(--hd-badge-size,16px);height:var(--hd-badge-size,16px);
  flex:none;border-radius:50%;background:#fff;
  /* The badge's own colour as a ring, so a white disc still has an edge on a
     pale card. Border-box means it comes out of the size rather than adding to
     it, and the mark stays the size set in Settings.

     A hairline rather than a band: at this size 2px reads as a blob with a
     colour round it rather than a marked-out disc. */
  border:1px solid var(--hd-pill-tutor-bg,var(--hd-badge-fallback));
  display:inline-flex;align-items:center;justify-content:center;
}
/* 2px of the disc left showing all the way round the artwork, so the mark sits
   on the light rather than filling it edge to edge. box-sizing:border-box means
   the padding comes out of the size rather than adding to it, so the badge
   stays exactly the size set in Settings. */
.hd-badge img{object-fit:cover;padding:2px;}

/* On a card the badge is the mark alone, beside the name, with the wording in
   a tooltip. It carries the badge's own background, so the 2px showing round
   the artwork reads as that college's colour rather than a generic ring. */
.hd-badge-marks{display:inline-flex;gap:4px;vertical-align:middle;margin-left:7px;}
/* Each badge set gets its own class - is-verified, is-founder - so a set can be
   styled apart later without touching the other two. Nothing on them yet: they
   all take their colours from the term or from the tutor / practitioner pair. */
/* Tooltip on a card's badge marks.
   The name was on a title attribute, which meant the browser's own tooltip: a
   second of delay and the operating system's styling in the middle of the card.
   This is the same words, immediately, in the site's own colours.

   Built from data-tip rather than title so the two do not both appear. The name
   is still on aria-label, so a screen reader announces it without needing to
   hover - which matters, because there is no hover on a phone and these marks
   are deliberately not focusable: a tab stop on every badge on every card would
   be a lot of stops for a word already announced. */
.hd-badge-mark,.hd-badge[data-tip]{position:relative;}
.hd-badge-mark[data-tip]::after,
.hd-badge[data-tip]::after{
  content:attr(data-tip);
  position:absolute;bottom:calc(100% + 7px);left:50%;transform:translateX(-50%);
  background:var(--hd-ink);color:var(--hd-card);
  padding:5px 9px;border-radius:var(--hd-radius-sm);
  font-size:.68rem;font-weight:600;letter-spacing:.03em;text-transform:none;
  /* Bounded and wrapping rather than nowrap: .tutor-card and .course-card both
     carry overflow:hidden to clip the image to the card's corners, so a tooltip
     wide enough to leave the card would be cut off rather than overhang it. A
     long verification name wraps onto two lines instead. */
  line-height:1.3;white-space:normal;width:max-content;max-width:150px;
  pointer-events:none;
  opacity:0;visibility:hidden;transition:opacity .12s ease;z-index:6;
}
/* BOTH selectors here, matching the rule above that creates the tooltip. On
   30 July the pill was added to the creating rule and not to this one, so its
   tooltip existed with the right words in it and was never unhidden - and
   checking the element's properties showed it "correct" the whole time. */
.hd-badge-mark[data-tip]:hover::after,
.hd-badge[data-tip]:hover::after{opacity:1;visibility:visible;}
.hd-badge-mark{
  display:inline-flex;align-items:center;justify-content:center;flex:none;
  width:var(--hd-badge-size,16px);height:var(--hd-badge-size,16px);
  border-radius:50%;background:#fff;
  border:1px solid var(--hd-pill-tutor-bg,var(--hd-badge-fallback));
}
.hd-badge-mark img{width:100%;height:100%;border-radius:50%;object-fit:cover;padding:2px;display:block;}
/* The badge's colour on the glyph rather than behind it, so the icon still
   reads as that college's while the disc stays white. */
.hd-badge-mark i{font-size:calc(var(--hd-badge-size,16px) * .72);color:var(--hd-pill-tutor-bg,var(--hd-badge-fallback));}
.hd-badge i{font-size:calc(var(--hd-badge-size,16px) * .72);color:var(--hd-badge-fallback);}

/* Tutor social links (only rendered for filled-in profiles) */
.tutor-social{display:flex;flex-wrap:wrap;gap:14px;margin-top:8px;}
.tutor-social a{
  display:inline-flex;align-items:center;justify-content:center;
  width:42px;height:42px;border-radius:50%;font-size:22px;
  color:var(--hd-gold);background:var(--hd-card);
  border:1px solid rgba(125,97,56,.35);transition:color .15s ease,border-color .15s ease;
}
.tutor-social a:hover{color:var(--hd-bronze);border-color:var(--hd-gold);}

/* Membership logos on a tutor profile.
   A white tile behind each one, because several of the logos are transparent
   and would otherwise sit straight on the parchment and look like a mistake.
   Sized by height rather than width: all four are supplied at 188px tall with
   different widths, so a common height is what makes them line up. */
.tutor-memberships{display:flex;flex-wrap:wrap;gap:10px;align-items:center;}
.tutor-memberships .membership{
  display:flex;align-items:center;justify-content:center;
  background:#fff;border:1px solid var(--hd-line);border-radius:var(--hd-radius-md);padding:8px 12px;
  transition:border-color .15s ease,box-shadow .15s ease;
}
.tutor-memberships .membership:hover{
  border-color:var(--hd-gold);box-shadow:0 2px 8px rgba(92,67,39,.10);
}
.tutor-memberships img{height:34px;width:auto;display:block;}

/* About-the-tutor card on course pages */
.tutor-bio{
  margin-top:48px;padding:30px;
  display:grid;grid-template-columns:150px 1fr;gap:28px;align-items:start;
}
.tutor-bio .txt p{max-width:60em;}
.tutor-bio .pic img{width:150px;height:150px;border-radius:50%;object-fit:cover;display:block;}
.tutor-bio h2{font-size:1.4rem;margin-bottom:.35em;}
.tutor-bio h2 a{color:var(--hd-ink);}
.tutor-bio h2 a:hover{color:var(--hd-bronze);}
.tutor-bio p{margin:0 0 16px;font-size:.95rem;}
.tutor-bio .links{display:flex;gap:10px;flex-wrap:wrap;}
@media (max-width:600px){
  .tutor-bio{grid-template-columns:1fr;text-align:center;}
  /* Both cases. A tutor with a photograph renders an <img>, one without
     renders .avatar-default, and only the first was ever being centred. */
  .tutor-bio .pic img,
  .tutor-bio .pic .avatar-default{margin:0 auto;}
  .tutor-bio .links{justify-content:center;}
}

/* Tutor profile */
.tutor-profile{display:grid;grid-template-columns:320px 1fr;gap:40px;align-items:start;margin-bottom:20px;}
.tutor-profile .side{display:flex;flex-direction:column;gap:20px;position:sticky;top:100px;}
.tutor-profile .portrait{overflow:hidden;margin:0;}
/* Square whatever the file turns out to be, so a photo uploaded before the
   square size existed still looks right until it is regenerated. */
.tutor-profile .portrait img{display:block;width:100%;height:auto;aspect-ratio:1/1;object-fit:cover;}
.contact-panel{padding:24px 28px;margin-bottom:26px;}
.contact-panel h3{font-size:.78rem;letter-spacing:.18em;text-transform:uppercase;color:var(--hd-accent);}
.contact-panel ul{list-style:none;margin:0 0 14px;padding:0;display:flex;flex-wrap:wrap;gap:10px 36px;}
.contact-panel li{display:flex;gap:11px;align-items:baseline;margin-bottom:0;font-size:.92rem;color:var(--hd-ink-muted);word-break:break-word;}
.contact-panel li i{color:var(--hd-gold);font-size:17px;flex-shrink:0;}
/* Only where theme.js has actually made it copyable - a phone still gets a plain
   link, and should not be told it can click to copy. */
.contact-panel a.hd-tel[role="button"]{cursor:copy;}
.contact-panel a.hd-tel.is-copied{color:var(--hd-bronze);font-weight:600;}
.contact-panel .offers-heading{margin-top:18px;}
.contact-panel .tags{margin-top:6px;}
.contact-panel .offers-more{margin:12px 0 0;font-size:.85rem;color:var(--hd-ink-muted);}
.contact-panel .offers-more i{vertical-align:-2px;}
.tutor-courses{margin-top:56px;}
.tutor-courses .hd-rule span,.tutor-gallery .hd-rule span,.hd-rule.is-wide span{flex:1;width:auto;}
/* is-wide is the modifier to reach for on any new block that wants the long
   rule. The two selectors beside it are older and stay for the blocks that
   already rely on them. */
.hd-rule.is-wide{margin:36px 0 24px;}
.tutor-courses h2{margin-bottom:26px;}
@media (max-width:820px){
  .tutor-profile{grid-template-columns:1fr;}
  .tutor-profile .side{position:static;max-width:420px;}
  /* One contact method per line. The wrapping row above is right on a wide
     panel, where two or three sit neatly across; at phone width it put the
     email and the phone number shoulder to shoulder, and both are tappable
     links, so they were easy to hit by mistake (James, 29 July). */
  .contact-panel ul{flex-direction:column;gap:12px;}
}

/* About / walnut strip */
/* The event banner (inc/banner.php). Borrows the strip's own gradient and ink
   rather than introducing a colour, so it belongs to the site in both light and
   dark and needs nothing added when either palette changes. A dismissible one
   is printed hidden and revealed by theme.js, so it never appears and then
   vanishes in front of somebody who closed it yesterday. */
.hd-banner{
  background:linear-gradient(135deg,var(--hd-strip-from) 0%,var(--hd-strip-to) 100%);
  color:var(--hd-strip-ink);
}
.hd-banner .hd-wrap{
  display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  padding-top:12px;padding-bottom:12px;
}
.hd-banner-words{flex:1 1 260px;min-width:0}
.hd-banner-words strong{margin-right:8px}
.hd-banner-link{
  color:var(--hd-strip-ink);border:1px solid var(--hd-gold-soft);
  border-radius:999px;padding:5px 14px;text-decoration:none;white-space:nowrap;
}
.hd-banner-link:hover,.hd-banner-link:focus{background:rgba(238,227,198,.14)}
.hd-banner-x{
  background:none;border:0;color:var(--hd-strip-ink);cursor:pointer;
  font-size:22px;line-height:1;padding:0 4px;opacity:.75;
}
.hd-banner-x:hover,.hd-banner-x:focus{opacity:1}
@media (max-width:600px){
  .hd-banner .hd-wrap{align-items:flex-start}
}

/* The profile gallery: small tiles, full width, and no gaps whatever the number
   of pictures (James, 13 August).

   FLEXBOX RATHER THAN GRID, and that is the whole point. A grid's columns are
   shared by every row, so a last row holding fewer pictures than there are
   columns always leaves empty cells and nothing can stretch them. In a wrapping
   flex row each item grows to fill what is left, so every row finishes flush -
   including the last one, whether it holds five pictures or one.
   flex-basis is the size a tile wants to be and grow is what it does about the
   remainder, so the count decides the width and the pattern never has holes.

   The bento reading survives as WIDTH rather than height: every sixth tile
   takes roughly twice the room of its neighbours. Heights stay equal because a
   taller item in a wrapping flex row sets the height of that whole row and the
   rhythm goes with it. */
/* Space on both sides, not just above. The gallery can now sit in four places
   on a profile, and in three of them whatever follows brings its own top margin
   - but directly above the contact card it was landing flush against it
   (James, 13 August). A block that can be moved has to carry its own room. */
.tutor-gallery{margin:48px 0}
.hd-gallery{display:flex;flex-wrap:wrap;gap:10px}
/* max-width is the whole of the "few tiles" fix (James, 13 August 2026).
   flex-grow hands a lone tile the entire row while the height stays at 150px,
   so object-fit crops a thin band out of the middle of the picture and stretches
   it - which is what a gallery holding one item looked like, photograph or
   video alike. The cap only bites while there is spare room going: as soon as
   there are enough tiles that each would sit under it, growth resumes and the
   row fills exactly as before. Rows of four upwards are untouched. */
.hd-gallery-item{
  display:block;flex:1 1 130px;height:150px;max-width:260px;overflow:hidden;
  border-radius:var(--hd-radius-md,8px);background:var(--hd-card);
}
/* Which tiles are wide is decided in PHP from the listing's own id, so a
   profile always looks the same and two profiles do not - see
   hd_gallery_wide_indexes(). It used to be every sixth, which read as a rule. */
.hd-gallery-item.is-wide{flex-grow:2;flex-basis:280px;max-width:520px}
.hd-gallery-item img{width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .35s ease}
.hd-gallery-item:hover img,.hd-gallery-item:focus img{transform:scale(1.04)}
/* A video or a track (inc/media-embeds.php). The tile is its poster, stored
   here like any other picture, with a mark in the corner - a play circle for
   video, a waveform for sound. Nothing on this tile reaches the provider: it is
   a link, and the visitor decides whether to follow it. */
.hd-gallery-item.is-media{position:relative}
.hd-gallery-play{
  position:absolute;right:8px;bottom:8px;width:34px;height:34px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;pointer-events:none;
  background:rgba(35,25,14,.72);color:#EEE3C6;font-size:20px;line-height:1;
}
.hd-gallery-item.is-media:hover .hd-gallery-play,
.hd-gallery-item.is-media:focus .hd-gallery-play{background:rgba(35,25,14,.92)}
@media (max-width:600px){
  .hd-gallery-item{flex-basis:100px;height:110px;max-width:190px}
  .hd-gallery-item.is-wide{flex-basis:210px;max-width:340px}
  .hd-gallery-play{width:28px;height:28px;font-size:17px;right:6px;bottom:6px}
}
@media (prefers-reduced-motion:reduce){
  .hd-gallery-item img{transition:none}
  .hd-gallery-item:hover img,.hd-gallery-item:focus img{transform:none}
}

/* The lightbox. Built by theme.js when a tile is clicked and removed again on
   close, so nothing of it exists in the page until it is wanted. Walnut rather
   than black: the site's own dark, not a browser's. */
.hd-lightbox{
  position:fixed;inset:0;z-index:9999;display:flex;align-items:center;
  justify-content:center;padding:24px;background:rgba(35,25,14,.92);
}
.hd-lightbox img{
  max-width:min(1100px,94vw);max-height:88vh;width:auto;height:auto;
  border-radius:var(--hd-radius-md,8px);display:block;
}
.hd-lightbox-x{
  position:absolute;top:14px;right:18px;width:44px;height:44px;border-radius:50%;
  border:1px solid rgba(238,227,198,.4);background:transparent;color:#EEE3C6;
  font-size:26px;line-height:1;cursor:pointer;
}
.hd-lightbox-x:hover,.hd-lightbox-x:focus{background:rgba(238,227,198,.14)}
/* The arrows sit against the edges rather than beside the picture, so they stay
   put whatever shape the photograph is. Hidden entirely when there is only one. */
.hd-lightbox-arrow{
  position:absolute;top:50%;transform:translateY(-50%);
  width:52px;height:52px;border-radius:50%;
  border:1px solid rgba(238,227,198,.4);background:transparent;color:#EEE3C6;
  font-size:30px;line-height:1;cursor:pointer;
}
.hd-lightbox-arrow.is-prev{left:14px}
.hd-lightbox-arrow.is-next{right:14px}
.hd-lightbox-arrow:hover,.hd-lightbox-arrow:focus{background:rgba(238,227,198,.14)}
@media (max-width:600px){
  .hd-lightbox-arrow{width:44px;height:44px;font-size:26px}
  .hd-lightbox-arrow.is-prev{left:6px}
  .hd-lightbox-arrow.is-next{right:6px}
}
/* The second kind of item in the same lightbox: a video or a track. The poster,
   its title, and one button out to where the recording lives. The poster is the
   file the tile already loaded, so opening this fetches nothing at all, and the
   provider is reached only if somebody presses the button. */
/* READ THIS BEFORE HIDING ANYTHING ELSE IN HERE. The lightbox swaps between a
   picture and a card by setting .hidden on one and clearing it on the other -
   and [hidden] is a user-agent rule that loses to ANY class setting display.
   .hd-lightbox-card sets flex and .hd-lightbox img sets block, so both were
   ignoring it and appearing together the moment a gallery held a photograph and
   a video at once (James, 14 August 2026). Every element this thing hides has to
   be told explicitly, so anything added here needs a line below. */
.hd-lightbox img[hidden],
.hd-lightbox-card[hidden],
.hd-lightbox-go[hidden]{display:none}
.hd-lightbox-card{
  display:flex;flex-direction:column;align-items:center;gap:16px;
  max-width:min(760px,92vw);text-align:center;
}
.hd-lightbox-card img{max-height:56vh}
.hd-lightbox-title{margin:0;color:#EEE3C6;font-size:1.15rem;line-height:1.35}
.hd-lightbox-go{
  display:inline-block;padding:12px 22px;border-radius:var(--hd-radius-md,8px);
  border:1px solid rgba(238,227,198,.5);background:transparent;color:#EEE3C6;
  text-decoration:none;font-size:1rem;
}
.hd-lightbox-go:hover,.hd-lightbox-go:focus{background:rgba(238,227,198,.14);color:#EEE3C6}
/* The player, once somebody has asked for it. Only ever present when playing on
   the page is switched on at Healing Drum > Images - until then the card holds a
   poster and a button out, and no third party is contacted at all. */
.hd-lightbox-card.is-playing{max-width:min(1100px,92vw)}
.hd-lightbox-frame{
  width:min(1100px,92vw);aspect-ratio:16/9;max-height:80vh;
  border:0;border-radius:var(--hd-radius-md,8px);background:#000;display:block;
}
/* The two audio ones are short and a fixed height, so they get their own from
   the provider rather than a video's shape. */
.hd-lightbox-frame.is-short{aspect-ratio:auto;max-height:none;background:transparent}

/* The picture banner. No background of its own: whatever the image is, it sits
   on the page rather than in a coloured box, so a poster with its own edges is
   not framed twice. */
.hd-picture{margin:0 0 28px}
.hd-picture .hd-wrap{padding-top:20px;padding-bottom:0}
.hd-picture-img{
  display:block;width:100%;height:auto;border-radius:var(--hd-radius-md,8px);
}
.hd-picture a{display:block;text-decoration:none}

.hd-strip{
  background:linear-gradient(135deg,var(--hd-strip-from) 0%,var(--hd-strip-to) 100%);
  color:var(--hd-strip-ink);padding:72px 0;
}
.hd-strip .hd-wrap{display:grid;grid-template-columns:auto 1fr;gap:44px;align-items:center;}
.hd-strip .mark img{width:150px;height:150px;}
.hd-strip h2{color:var(--hd-strip-ink);}
.hd-strip p{color:rgba(238,227,198,.82);max-width:44em;}
.hd-strip .hd-eyebrow{color:var(--hd-gold-soft);}
.hd-strip a:not(.hd-btn){color:var(--hd-gold-soft);}
/* The colour override this rule used to carry, walnut-deep text on gold, was
   3.55:1 against the old gold and would have been 1.98:1 against the new one.
   Dropped so the button inherits color:var(--hd-card) like every other button
   on the site, which measures 5.31:1. */
.hd-strip .hd-btn{background:var(--hd-gold);}
@media (max-width:700px){
  .hd-strip .hd-wrap{grid-template-columns:1fr;text-align:center;}
  .hd-strip .mark img{width:110px;height:110px;}
}

/* ---------------------------------------------------------------------------
   5. Content pages, archives, single
--------------------------------------------------------------------------- */
.page-hero{
  background:radial-gradient(120% 120% at 50% 0%, var(--hd-hero-from) 0%, var(--hd-hero-mid) 78%);
  border-bottom:1px solid var(--hd-line);padding:54px 0 46px;
}
/* Breadcrumb: three steps, sitting above the eyebrow in the page hero. The
   current page is plain text, so only the steps you can actually go to look
   like links. Long titles wrap rather than stretching the row. */
.hd-crumbs{margin-bottom:14px;font-size:.82rem;}
.hd-crumbs ol{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;align-items:center;gap:9px;}
.hd-crumbs li{display:flex;align-items:center;gap:9px;color:var(--hd-ink-muted);min-width:0;}
.hd-crumbs li + li::before{content:"\203A";color:var(--hd-gold);font-size:1rem;line-height:1;}
.hd-crumbs a{color:var(--hd-bronze);font-weight:600;text-decoration:none;}
.hd-crumbs a:hover{color:var(--hd-ink);text-decoration:underline;text-underline-offset:3px;}
.hd-crumbs [aria-current]{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
@media (max-width:600px){.hd-crumbs [aria-current]{max-width:60vw;}}

.page-hero h1{margin-bottom:0;}
/* The badge sits directly under the name with no margin of its own, and the
   heading's 1.15 line-height leaves only a few pixels below the baseline - far
   less than Mulish's descenders. So a name with a y, g, j, p or q hung into the
   pill, while a name without one looked fine (James, 29 July). The gap goes
   here rather than on the h1, so hero pages with no badge are unaffected. */
.page-hero .hd-badge-rows{margin-top:12px;}
/* Two rows: verification and founder share the top one, the college badges take
   the one below (James, 30 July). A flex column with a gap rather than a margin
   on each row, because a gap only exists BETWEEN two children - so one row on
   its own costs nothing, and a set that is empty or switched off under Healing
   Drum, Badges leaves no space behind it. hd_badge_rows() prints no wrapper at
   all when both rows are empty, so a listing with no badges does not get the
   12px above either.
   8px rather than the old 12+10: the pills sit 7px apart across a row, so the
   two directions now read as one grid rather than two decisions. */
.hd-badge-rows{display:flex;flex-direction:column;gap:8px;}
.hd-badge-rows .hd-badges{margin:0;}
.page-hero p.sub{margin:12px 0 0;max-width:44em;}
/* The gold hero divider, matched to the front page's length (its copy column is
   about 34em because the drum takes the right of that hero). */
.page-hero .hd-rule{max-width:34em;margin:16px 0;}
.page-hero .hd-rule span{flex:1;width:auto;}

.site-main{padding:56px 0 80px;}
.entry-content{max-width:760px;}
.entry-content a{text-decoration:underline;text-decoration-color:rgba(125,97,56,.5);text-underline-offset:3px;}
.entry-content img{border-radius:var(--hd-radius-lg);}

/* Standard Page template: the page body inside a centred parchment card. */
.page-card{max-width:840px;margin-inline:auto;padding:38px 44px;}
.page-card .entry-content{max-width:none;}
.page-card .featured{margin:0 0 26px;}
.page-card .featured img{display:block;width:100%;height:auto;border-radius:var(--hd-radius-md);}
@media (max-width:600px){.page-card{padding:26px 22px;}}

/* Centred Page template: a left-aligned hero, with only the main content column centred. */
.page-centred .entry-content{margin-inline:auto;}
.page-centred .single-featured{max-width:760px;margin-inline:auto;}

/* The Journey Drum plugin is an interactive iframe, not body text, so free it
   from the 760px readable-text cap and let it fill the full content width.
   The plugin renders the iframe at width:100%, so the container is what sets
   how wide it can be. */
.entry-content:has(.journey-drum-frame){max-width:none;}
/* The one heading a tutor can use, from the editor's format dropdown. The size
   comes from the global h3 rule, 1.2rem, which is a step above body text rather
   than a shout. What it needs here is air above it: the global heading rule sets
   a bottom margin only, which is right for a heading that opens a block and
   wrong for one arriving partway through running prose. */
.entry-content h3{margin-top:1.7em;}
.entry-content h3:first-child{margin-top:0;}
.entry-content ul,.entry-content ol{color:var(--hd-ink-muted);padding-left:1.3em;}
.entry-content li{margin-bottom:.35em;}
.wp-block-image figcaption{color:var(--hd-ink-muted);font-size:.85rem;text-align:center;}

.entry-meta{font-size:.85rem;color:var(--hd-ink-muted);margin-bottom:26px;}
.entry-meta i{color:var(--hd-gold);vertical-align:-2px;margin-right:6px;}

.single-featured{margin:0 0 34px;}
/* width:100% was missing here, so the image sat at its own width inside a wider
   column and stopped short of the panel below it. Every other block image in
   the theme sets this; this one was simply overlooked. */
/* Large, not pill: this is the big photo at the top of a course or profile, and
   it landed in the pill bucket only because it happened to be 20px when the
   scale was collapsed. Pill is for buttons and the search field, so leaving it
   there meant squaring off the buttons squared off this photo with them. */
.single-featured img{display:block;width:100%;height:auto;border-radius:var(--hd-radius-lg);box-shadow:0 20px 44px rgba(92,67,39,.16);}

/* Finished-course notice */
.course-finished{
  display:flex;gap:12px;align-items:center;padding:16px 22px;margin:0 0 26px;
  font-weight:600;color:var(--hd-ink);
}
.course-finished i{font-size:22px;color:var(--hd-bronze);flex-shrink:0;}
.course-finished a{text-decoration:underline;text-underline-offset:3px;}

/* Course single details panel */
/* Panels and cards run the full width of the wrap, matching the tutor profile
   and lining up with the heading above them. Only running text is held to a
   readable measure (.entry-content); capping the panels too left a third of the
   page empty down the right-hand side. */
/* Course profile: the tutor page's shape applied to a course. The picture, the
   facts and the booking button ride in a sticky left column, and the
   description gets a column of its own at roughly 712px.

   That measure is the point of the whole arrangement. It is produced by the
   layout rather than by capping .entry-content at 760px inside a 1072px box,
   which put the entire 312px shortfall down the right-hand side and read as
   misalignment rather than as a measure.

   .course-details needs no override to stack: its auto-fit minimum is 210px and
   two of those cannot fit in 320px, so it collapses to one column by itself.
   The booking button keeping grid-column:1/-1 still spans that single column. */
.course-profile{display:grid;grid-template-columns:320px 1fr;gap:40px;align-items:start;margin-bottom:20px;}
.course-profile .side{display:flex;flex-direction:column;gap:20px;position:sticky;top:100px;}
/* The gap on .side does the spacing now, so the stacked margins come off. */
.course-profile .single-featured,.course-profile .course-details{margin:0;}
.course-profile .entry-content{max-width:none;}
@media (max-width:820px){
  .course-profile{grid-template-columns:1fr;}
  .course-profile .side{position:static;max-width:420px;}
}

.course-details{
  margin:0 0 34px;padding:26px 28px;
  display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:16px 30px;
}
.course-details .item{display:flex;gap:14px;align-items:flex-start;}
.course-details .item i{font-size:24px;color:var(--hd-gold);margin-top:2px;}
.course-details .label{font-weight:600;font-size:.7rem;letter-spacing:.14em;text-transform:uppercase;color:var(--hd-accent);display:block;}
.course-details .value{color:var(--hd-ink);font-weight:600;}
/* Optional free-text note a tutor can add under a price (instalments, deposit
   terms). Smaller and lighter than the amount, on its own line beneath it. */
.course-details .hd-price-note{display:block;margin-top:3px;font-size:.8rem;font-weight:400;color:var(--hd-ink-muted);}
.course-details .book{grid-column:1/-1;margin-top:6px;}
@media (max-width:600px){.course-details{grid-template-columns:1fr;}}

/* 404 divider: the lines stretch instead of sitting at their fixed 56px, and the
   whole rule is held to the same 34em as the words below it. That makes the
   heading, the rule and the message read as one centred column rather than a
   wide heading over a small ornament. */
.hd-404-rule{max-width:34em;margin-inline:auto;}
.hd-404-rule span{flex:1;width:auto;}

/* 404 words: the readable measure applies, but centred rather than left-aligned
   inside a centred column, and the paragraph cap that .entry-content normally
   leaves alone is not wanted on a page this short. */
.hd-404-words{max-width:34em;margin-inline:auto;text-align:center;}

/* Blog list */
.post-list{display:grid;gap:22px;grid-template-columns:repeat(2,1fr);}
@media (max-width:700px){.post-list{grid-template-columns:1fr;}}

/* Pagination */
.hd-pagination{margin-top:44px;display:flex;gap:8px;flex-wrap:wrap;}
.hd-pagination .page-numbers{
  display:inline-flex;align-items:center;justify-content:center;min-width:42px;height:42px;
  padding:0 14px;border-radius:var(--hd-radius-pill);background:var(--hd-card);border:1px solid var(--hd-line);
  color:var(--hd-ink);font-weight:600;font-size:.9rem;
}
.hd-pagination .page-numbers.current{background:var(--hd-accent);border-color:var(--hd-accent);color:var(--hd-card);}
.hd-pagination a.page-numbers:hover{border-color:var(--hd-gold);color:var(--hd-bronze);}

/* Search + 404 */
.search-form{display:flex;gap:10px;max-width:480px;}
.search-form input[type=search]{
  flex:1;padding:12px 18px;border-radius:var(--hd-radius-pill);border:1px solid var(--hd-line);
  background:var(--hd-card);font-family:var(--hd-font);font-size:.95rem;color:var(--hd-ink);
}
.search-form input[type=search]:focus{outline:2px solid var(--hd-accent);outline-offset:1px;}

/* Forms (comments, contact plugins). Field chrome matches the contact form:
   the same padding, radius, stronger resting border, and gold focus ring. */
input[type=text],input[type=email],input[type=url],textarea{
  width:100%;padding:13px 18px;border-radius:var(--hd-radius-lg);border:1px solid var(--hd-line-strong);
  background:var(--hd-card);font-family:var(--hd-font);font-size:.95rem;color:var(--hd-ink);
}
textarea{min-height:140px;resize:vertical;}
input[type=text]:focus,input[type=email]:focus,input[type=url]:focus,textarea:focus{
  outline:none;border-color:var(--hd-gold);box-shadow:0 0 0 3px rgba(125,97,56,.18);
}

/* ---------------------------------------------------------------------------
   6. Footer
--------------------------------------------------------------------------- */
.site-footer{
  background:linear-gradient(180deg,var(--hd-strip-from) 0%,var(--hd-strip-to) 100%);
  color:rgba(238,227,198,.8);margin-top:0;
}
.site-footer .top{padding:56px 0 40px;}
.site-footer .top .hd-wrap{display:grid;grid-template-columns:1.2fr 1fr 1fr auto;gap:44px;}
.site-footer h4{color:var(--hd-strip-ink);font-size:.78rem;letter-spacing:.18em;text-transform:uppercase;margin-bottom:16px;}
.site-footer .brand img{height:56px;width:auto;margin-bottom:14px;}
.site-footer p{color:rgba(238,227,198,.72);font-size:.92rem;}
.site-footer ul{list-style:none;margin:0;padding:0;}
.site-footer li{margin-bottom:9px;}
.site-footer a{color:rgba(238,227,198,.85);font-size:.92rem;}
.site-footer a:hover{color:var(--hd-gold-soft);}
.site-footer .contact li{display:flex;gap:10px;align-items:baseline;}
.site-footer .contact i{color:var(--hd-gold-soft);font-size:17px;}
/* A second heading inside a footer column, which today means "Your privacy"
   sitting under Contact. Without room above it, it reads as the last line of
   the list before it rather than the start of something new. Matched on the
   list it follows, so no column needs a class adding to it. */
.site-footer .top ul + h4{margin-top:30px;}
.footer-social{display:flex;gap:16px;margin-top:18px;font-size:23px;}
.footer-social a{color:var(--hd-gold-soft);}

/* Footer brand strip: the logo mark and tagline, full width below the columns. */
.footer-brand-strip{border-top:1px solid rgba(238,227,198,.14);padding:24px 0;}
.footer-brand-strip .hd-wrap{display:flex;align-items:center;justify-content:center;gap:18px;flex-wrap:wrap;text-align:center;}
.footer-brand-strip img{height:46px;width:auto;flex-shrink:0;}
.footer-brand-strip p{margin:0;max-width:54ch;}
.footer-brand-strip .footer-social{margin:0;}

/* "More drum tutors in {region}" contextual link on single course/tutor pages. */
.hd-region-link{margin:30px 0 0;}
.hd-region-link a{display:inline-flex;align-items:center;gap:8px;color:var(--hd-bronze);font-weight:600;}
.hd-region-link a:hover{color:var(--hd-gold);}
.hd-region-link i{color:var(--hd-gold);font-size:18px;}
.footer-social a:hover{color:var(--hd-strip-ink);}
.site-footer .bottom{
  border-top:1px solid rgba(238,227,198,.14);padding:20px 0;
  font-size:.8rem;color:rgba(238,227,198,.55);
}
.site-footer .bottom .hd-wrap{display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;}
/* Four columns need an intermediate step. Three fitted down to 820px; a fourth
   is squeezed well before that, so it pairs up first and stacks after. */
@media (max-width:1000px){.site-footer .top .hd-wrap{grid-template-columns:1fr 1fr;gap:36px;}}
@media (max-width:820px){.site-footer .top .hd-wrap{grid-template-columns:1fr;gap:32px;}}

/* Display and accessibility.

   Printed hidden and revealed by theme.js; the [hidden] rule is here because an
   author display rule beats the attribute on its own. The controls are native
   radios and a native checkbox, so keyboard behaviour, grouping and screen
   reader announcement all come from the browser and there is no ARIA to keep
   correct. accent-color tints the checked state without replacing the control,
   which would have meant rebuilding focus and keyboard handling by hand. */
.footer-display[hidden]{display:none;}
.footer-display fieldset{border:0;margin:0;padding:0;}
.footer-display label{
  display:flex;align-items:center;gap:9px;margin-bottom:9px;
  color:rgba(238,227,198,.85);font-size:.92rem;cursor:pointer;
}
.footer-display input{
  accent-color:var(--hd-gold-soft);
  width:16px;height:16px;margin:0;flex-shrink:0;cursor:pointer;
}
.footer-display label:hover{color:var(--hd-gold-soft);}
.hd-motion{margin-top:18px;padding-top:16px;border-top:1px solid rgba(238,227,198,.14);}

/* Contact page template: one full-width card in the tutor-profile style,
   holding the form and nothing else - the site is a directory, not an
   organisation, and the form is the one route in. */

/* The card holds a form, not an article, so the 760px readable-text cap does
   not apply to it. The message box is meant to run the full width of the card
   at every window size, and until now the cap on .entry-content stopped it
   reaching the card edge; the faint pre-v1.4.129 border simply hid the gap.
   Running text added to the page keeps the readable measure. */
.contact-panel .entry-content{max-width:none;}
.contact-panel .entry-content > p{max-width:760px;}

/* The privacy line beneath the form. */
.contact-privacy{
  display:flex;gap:9px;align-items:baseline;margin:22px 0 0;
  font-size:.88rem;color:var(--hd-ink-muted);
}
.contact-privacy i{color:var(--hd-gold);font-size:16px;}

/* Honeypot. Positioned off screen rather than display:none, because a bot that
   skips hidden fields still meets this one, and a person never can: it is out
   of the tab order and hidden from assistive technology in the markup. */
.hd-trap{position:absolute;left:-9999px;top:auto;width:1px;height:1px;overflow:hidden;}

/* ---------------------------------------------------------------------------
   Contact form (Contact Form 7)

   The plugin ships almost no styling of its own, so a form dropped onto a page
   arrives as raw browser controls in the middle of a designed site. These rules
   give its fields the same parchment, rule colour and rounded shape as the rest
   of the theme. The submit button already inherits the site button style.
--------------------------------------------------------------------------- */
/* Contact Form 7 6.1+ wraps its invisible technical fields in a <fieldset>,
   which otherwise shows as an empty bordered box above the first field. Its
   contents are all type=hidden, so removing the frame hides the box without
   touching the form. */
.wpcf7 .hidden-fields-container{border:0;margin:0;padding:0;}
.wpcf7 p{margin:0 0 18px;}
.wpcf7 label{display:block;font-weight:600;color:var(--hd-ink);margin-bottom:7px;}
.wpcf7 input[type=text],.wpcf7 input[type=email],.wpcf7 input[type=tel],
.wpcf7 input[type=url],.wpcf7 input[type=number],.wpcf7 input[type=date],
.wpcf7 select,.wpcf7 textarea{
  width:100%;font-family:var(--hd-font);font-size:1rem;color:var(--hd-ink);
  background:var(--hd-card);border:1px solid var(--hd-line-strong);border-radius:var(--hd-radius-lg);
  padding:13px 18px;
}
/* Short answers get short boxes; the message runs the full width of the card. */
.wpcf7 input[type=text],.wpcf7 input[type=email],.wpcf7 input[type=tel],
.wpcf7 input[type=url],.wpcf7 input[type=number],.wpcf7 input[type=date],
.wpcf7 select{max-width:640px;}
.wpcf7 textarea{min-height:170px;resize:vertical;}
.wpcf7 input[type=text]:focus,.wpcf7 input[type=email]:focus,.wpcf7 input[type=tel]:focus,
.wpcf7 input[type=url]:focus,.wpcf7 select:focus,.wpcf7 textarea:focus{
  outline:none;border-color:var(--hd-gold);box-shadow:0 0 0 3px rgba(125,97,56,.18);
}
.wpcf7 input::placeholder,.wpcf7 textarea::placeholder{color:rgba(92,67,39,.45);}
.wpcf7 .wpcf7-list-item{margin:0 20px 0 0;}
.wpcf7 .wpcf7-list-item-label{font-weight:400;}
.wpcf7-not-valid-tip{color:#b32d2e;font-size:.85rem;font-weight:600;margin-top:6px;}
.wpcf7 .wpcf7-response-output{
  margin:22px 0 0;padding:14px 18px;border-radius:var(--hd-radius-lg);
  border:1px solid var(--hd-line);background:var(--hd-card);
  font-weight:600;color:var(--hd-ink);
}
.wpcf7 form.sent .wpcf7-response-output{border-color:var(--hd-gold);}
.wpcf7 form.invalid .wpcf7-response-output,
.wpcf7 form.unaccepted .wpcf7-response-output,
.wpcf7 form.failed .wpcf7-response-output{border-color:#b32d2e;color:#b32d2e;}
.wpcf7-spinner{margin-left:12px;}

/* ---------------------------------------------------------------------------
   Message a tutor: the fold-out on the profile contact panel

   Native <details>: the <summary> is the ghost button, the body holds the
   Contact Form 7 form. theme.js animates the unfold by driving
   grid-template-rows between 0fr and 1fr; the [open] rule below is the
   resting state, so with script off the fold still opens and closes - it
   simply does so without the animation.
--------------------------------------------------------------------------- */
.hd-message{margin:18px 0 22px;}
.hd-message-toggle{
  display:flex;width:100%;justify-content:center;align-items:center;gap:9px;
  cursor:pointer;list-style:none;
}
.hd-message-toggle::-webkit-details-marker{display:none;}
/* The site's one caret, copied from .main-nav .menu-item-has-children > a::after
   deliberately rather than shared - the nav rule is scoped to .main-nav. */
.hd-message-toggle::after{
  content:"\e136";font-family:"Phosphor-Light";font-size:.72em;
  transition:transform .18s ease;
}
.hd-message[open] .hd-message-toggle::after{transform:rotate(180deg);}
.hd-message-label-short{display:none;}
@media (max-width:480px){
  .hd-message-label-full{display:none;}
  .hd-message-label-short{display:inline;}
}
.hd-message-body{
  display:grid;grid-template-rows:0fr;
  transition:grid-template-rows .25s ease;
}
.hd-message[open] .hd-message-body{grid-template-rows:1fr;}
.hd-message-body > .hd-message-fold{overflow:hidden;min-height:0;}
.hd-message-fold{
  background:var(--hd-message-bg);border:1px solid var(--hd-line);
  border-radius:var(--hd-radius-lg);margin-top:14px;
}
/* The padding lives on an inner box model via the form's own spacing plus
   this, so the fold clips cleanly mid-animation. */
.hd-message-fold > *{margin-left:22px;margin-right:22px;}
.hd-message-fold > .wpcf7{margin-top:20px;}
.hd-message-fold > .contact-privacy{margin-bottom:20px;}
/* Line breaks in the stored "message sent" wording are real line breaks. */
.hd-message .wpcf7-response-output{white-space:pre-line;}
/* The live email check. The tick is quiet; the error is not. */
/* Sent: the confirmation replaces the form in place rather than sitting under
   it - no jump, and no half-filled fields left on show. Script adds the
   class; with script off the message simply appears below the form. */
.hd-message .is-sent .wpcf7-form > :not(.wpcf7-response-output){display:none;}
.hd-message .is-sent .wpcf7-response-output{margin-top:0;border-color:var(--hd-marked);}
.hd-message .hd-message-match{margin:6px 0 0;font-size:.85rem;font-weight:600;}
.hd-message .hd-message-match.is-ok{color:var(--hd-marked);}
.hd-message .hd-message-match.is-error{color:var(--hd-error);}
/* The word counter under the message box: quiet until the message is too
   long, which is the only state that stops it being sent. */
.hd-message .hd-message-count{margin:6px 0 0;font-size:.85rem;color:var(--hd-ink-muted);}
.hd-message .hd-message-count.is-error{color:var(--hd-error);font-weight:600;}
.hd-message input.is-error{border-color:var(--hd-error);}
.hd-message .wpcf7-not-valid-tip{color:var(--hd-error);}

/* ---------------------------------------------------------------------------
   7. Misc / accessibility
--------------------------------------------------------------------------- */
.screen-reader-text{
  border:0;clip:rect(1px,1px,1px,1px);clip-path:inset(50%);height:1px;width:1px;
  margin:-1px;overflow:hidden;padding:0;position:absolute;word-wrap:normal!important;
}
.skip-link{
  position:absolute;left:-9999px;top:0;z-index:999;
  background:var(--hd-strip-from);color:var(--hd-strip-ink);padding:12px 18px;border-radius:0 0 var(--hd-radius-md) 0;
}
.skip-link:focus{left:0;color:var(--hd-card);}

/* Back to top (James, 7 August 2026): a fixed button, bottom right, printed by
   footer.php on every page. Invisible until theme.js adds .is-visible after
   roughly a screen of scrolling; the class changes only opacity and transform,
   and the button is position:fixed, so nothing in the page ever moves for it -
   the lesson of the header toggle, learned earlier the same day. The jump
   itself is native anchor navigation to #top: html{scroll-behavior:smooth}
   further up makes it glide, and every motion rule that cancels smoothness
   cancels it here too, with this file none the wiser. pointer-events keeps
   the invisible button unclickable and out of everyone's way; it never
   carries [hidden], so there is no attribute fight to lose. The colours are
   the theme variables, so it follows light and dark by itself. */
.hd-top{
  position:fixed;right:18px;bottom:calc(18px + env(safe-area-inset-bottom,0px));z-index:50;
  display:inline-flex;align-items:center;justify-content:center;
  width:44px;height:44px;border-radius:50%;
  background:var(--hd-card);border:1px solid var(--hd-line);color:var(--hd-walnut);
  box-shadow:0 6px 18px rgba(59,50,38,.18);
  font-size:20px;line-height:1;text-decoration:none;
  opacity:0;pointer-events:none;transform:translateY(8px);
  transition:opacity .25s ease,transform .25s ease;
}
.hd-top.is-visible{opacity:1;pointer-events:auto;transform:none;}
.hd-top:hover{border-color:var(--hd-gold);color:var(--hd-gold);}

/* Anchor copy buttons, members only, built by theme.js - its note carries the
   reasoning. Quiet on purpose: ninety-seven of them on the research page must
   read as furniture, not punctuation. Sized in em so the icon keeps its
   proportion from a section h2 down to a study h3, and vertical-align keeps
   it from stretching the heading's line box. */
.hd-anchor-copy{
  display:inline-flex;align-items:center;justify-content:center;
  margin-left:10px;padding:2px;border:0;background:none;cursor:pointer;
  font-size:.6em;line-height:1;vertical-align:middle;
  color:var(--hd-walnut);opacity:.4;transition:opacity .15s ease,color .15s ease;
}
.hd-anchor-copy:hover{opacity:1;color:var(--hd-gold);}

.aligncenter{display:block;margin-inline:auto;}
.alignleft{float:left;margin:0 1.5em 1em 0;}
.alignright{float:right;margin:0 0 1em 1.5em;}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important;}
}
