/* KidsColorsBook core presentation */
:root{
	--kcb-paper:#FFFCF5;
	--kcb-surface:#F7F2E8;
	--kcb-ink:#20211F;
	--kcb-muted:#60635E;
	--kcb-coral:#E96F5C;
	--kcb-yellow:#E7B84B;
	--kcb-sky:#78B7D2;
	--kcb-green:#8DBA98;
	--kcb-border:#DED8CC;
	--kcb-white:#FFFFFF;
	/* The accents above are the brand, and they stay exactly as they are
	   wherever they are a fill, a blob, a border or a button background. But
	   used as TEXT on a light background they measure 2.1:1 to 3.0:1, which is
	   below the 4.5:1 body-text floor and, for the sky and green, below even the
	   3:1 large-text floor. These are the same three hues darkened until they
	   clear 4.5:1 on --kcb-paper, for text use only. Never swap a fill to one of
	   these: the palette would go muddy for no benefit, since a fill has no
	   contrast requirement beyond the text sitting on it. */
	--kcb-coral-text:#DA371D;
	--kcb-sky-text:#347C9B;
	--kcb-green-text:#4D7F59;
	/* The WCAG floor drops to 3:1 once text is 24px or larger, so display-size
	   accent words do not need the full darkening above. These clear 3:1 and
	   nothing more, which keeps the hero bright: the coral moves by two values
	   and is indistinguishable from the brand colour. Use these ONLY at display
	   sizes. Anything at body size needs the -text pair. */
	--kcb-coral-display:#E96D5A;
	--kcb-sky-display:#469CC1;
	--kcb-radius:14px;
	--kcb-shadow:0 18px 50px rgba(32,33,31,.09);
	--kcb-shell:1200px;
	--kcb-copy:760px;
	/* Single source of truth for the header height. The mobile nav drawer sizes
	   itself off this, so the two can never drift apart again. */
	--kcb-header-h:70px;
	/* Section rhythm. Three beats, and the rule for choosing between them:
	   loose for a full-bleed statement that owns its own background, tight on
	   both sides of a seam where two neighbours share a background and would
	   otherwise read as one block split by dead space, default everywhere else.
	   The loose value is not new: .kcb-moment-finder-section was already using
	   it by hand, which is where it comes from. */
	--kcb-section-y:clamp(4rem,8vw,7rem);
	--kcb-section-y-loose:clamp(4.5rem,9vw,8rem);
	--kcb-section-y-tight:clamp(2.4rem,4.5vw,3.6rem);
	/* Motion vocabulary. Durations were spread across 8 hand-written values
	   between .15s and .7s, which is 4 perceptual steps pretending to be 8.
	   These are the 4. --kcb-ease is the signature curve that the reveals, the
	   card lifts and the nav underline already shared. Plain `ease` stays
	   literal for colour and opacity, where a custom curve is not perceptible
	   and a token would only add indirection. */
	--kcb-ease:cubic-bezier(.2,.75,.25,1);
	--kcb-dur-fast:.18s;
	--kcb-dur-base:.28s;
	--kcb-dur-slow:.45s;
	--kcb-dur-reveal:.7s;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;background:var(--kcb-paper);color:var(--kcb-ink);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Inter,Arial,sans-serif;font-size:17px;line-height:1.65;text-rendering:optimizeLegibility}
body.kcb-menu-open{overflow:hidden}
img{max-width:100%;height:auto}
a{color:inherit;text-underline-offset:.18em}
a:hover{text-decoration-thickness:2px}
button,input,textarea,select{font:inherit}
button,a,input,textarea,select,summary{outline-offset:4px}
:focus-visible{outline:3px solid #19789f;outline-offset:4px}
h1,h2,h3,h4{margin:0 0 .55em;font-weight:780;line-height:1.08;letter-spacing:-.026em}
h1{font-size:clamp(2.55rem,6vw,4.55rem)}
h2{font-size:clamp(2rem,4vw,3rem)}
h3{font-size:1.28rem}
p{margin:0 0 1.25rem}
ul,ol{padding-left:1.3rem}
.screen-reader-text{border:0;clip:rect(1px,1px,1px,1px);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-wrap:normal!important}
.screen-reader-text:focus{background:#fff;clip:auto!important;clip-path:none;color:#000;display:block;font-size:14px;height:auto;left:8px;line-height:normal;padding:12px 16px;top:8px;width:auto;z-index:99999}
.kcb-shell{width:min(calc(100% - 40px),var(--kcb-shell));margin-inline:auto}
.kcb-shell--narrow{max-width:var(--kcb-copy)}
.kcb-shell--wide{max-width:1080px}
.kcb-section{padding:var(--kcb-section-y) 0}
/* Section rhythm, the exceptions. Everything gets the default beat above; only
   two things change it.

   A full-bleed statement that owns its own background takes the loose beat, and
   that is declared with the rest of that section's styles rather than here.

   The other is a seam: where two neighbours share a background the boundary
   between them is invisible, so a full beat on each side reads as one block
   split by dead space instead of as two sections. Both sides tighten into a
   single beat. These are written as adjacency rather than as a class in the
   template on purpose, because every front-page section sits behind a show_*
   toggle in Appearance, KidsColorsBook, so which sections are neighbours
   changes with the settings and a hard-coded class would tighten against
   whatever happened to follow. The :has() half is a progressive enhancement:
   without it the seam is merely wide, never wrong.

   Two of the pairs below do not match in the default settings, and that is the
   mechanism working rather than dead weight. hero to portal-band needs the
   editorial block hidden, and how-v3 to social-wall needs show_freebie off,
   because the yellow newsletter panel normally sits between them and breaks the
   shared background. Turn either toggle off and the seam is already handled. Do
   not prune these by testing the default page alone. */
.kcb-hero-v3+.kcb-home-editorial,
.kcb-hero-v3+.kcb-portal-band,
.kcb-home-editorial+.kcb-portal-band,
.kcb-story-showcase+.kcb-colour-play-section,
.kcb-how-v3+.kcb-social-wall,
.kcb-events-hero+.kcb-featured-event,
.kcb-events-hero+.kcb-events-grid-section,
.kcb-featured-event+.kcb-events-grid-section{padding-top:var(--kcb-section-y-tight)}
.kcb-home-editorial:has(+.kcb-portal-band),
.kcb-story-showcase:has(+.kcb-colour-play-section),
.kcb-how-v3:has(+.kcb-social-wall),
.kcb-featured-event:has(+.kcb-events-grid-section){padding-bottom:var(--kcb-section-y-tight)}
.kcb-main{min-height:55vh}
.kcb-announcement{padding:.5rem 20px;background:var(--kcb-ink);color:#fff;text-align:center;font-size:.82rem;font-weight:750;letter-spacing:.02em}

/* --- Global chrome ---------------------------------------------------------
   header.php and footer.php emit every class below on every template, so the
   rules have to live in the always-enqueued stylesheet. They used to sit in
   motion.css, which inc/enqueue.php only loads on the front page and the six
   collection landings, leaving the header unsticky and the footer watermark
   as raw text everywhere else. */
.kcb-header--v3{position:sticky;top:0;z-index:70;background:rgba(255,252,245,.82);background:color-mix(in srgb,var(--kcb-paper) 82%,transparent);border-bottom:1px solid rgba(32,33,31,.08);backdrop-filter:blur(14px);transition:box-shadow var(--kcb-dur-base) ease,border-color var(--kcb-dur-base) ease,background-color var(--kcb-dur-base) ease}
/* Once the page has scrolled the header is floating over content rather than
   sitting at the top of it, so it earns a real edge instead of a hairline. */
.kcb-header--v3.is-stuck{border-bottom-color:transparent;background:rgba(255,252,245,.94);background:color-mix(in srgb,var(--kcb-paper) 94%,transparent);box-shadow:0 10px 34px rgba(32,33,31,.09)}
.kcb-header__inner{min-height:var(--kcb-header-h);display:flex;align-items:center;gap:clamp(1.5rem,4vw,3.25rem)}
.kcb-brand{flex:0 0 auto;max-width:220px;min-width:0}
.kcb-brand-lockup{display:inline-flex;align-items:center;gap:.8rem;text-decoration:none;color:var(--kcb-ink)}
.kcb-brand-lockup__text{font-size:1.08rem;font-weight:900;letter-spacing:-.04em}
.kcb-brand-lockup .custom-logo-link{display:flex;align-items:center;width:auto;max-width:100%;line-height:0}
.kcb-brand-lockup .custom-logo{display:block;width:auto;height:auto;max-width:100%;object-fit:contain}
/* The customiser values injected by inc/enqueue.php previously only reached
   .custom-logo, so the bundled fallback mark ignored them entirely. */
.kcb-brand-lockup--header .custom-logo,
.kcb-brand-lockup--header .kcb-brand-lockup__logo{height:var(--kcb-logo-height,54px);max-height:var(--kcb-logo-height,54px);max-width:var(--kcb-logo-max-width,190px)}
.kcb-brand-lockup--footer .custom-logo,
.kcb-brand-lockup--footer .kcb-brand-lockup__logo{height:70px;max-height:70px;max-width:230px}
.kcb-brand-lockup__logo{display:block;width:auto;object-fit:contain;filter:drop-shadow(0 8px 12px rgba(0,0,0,.08))}
/* kcb_default_logo_markup() wraps the mark in <picture> to offer the WebP first.
   display:contents removes that wrapper's own box, so the <img> keeps taking part
   in the flex row (header, footer) and in the absolutely positioned book stage
   exactly as the bare <img> it replaced did, and every rule above still lands. */
.kcb-brand-lockup picture,
.kcb-book-stage picture{display:contents}
.elementor-location-header .elementor-widget-theme-site-logo img{display:block;width:auto;max-width:100%;max-height:80px;object-fit:contain}
.kcb-elementor-content{width:100%;max-width:none;margin:0;padding:0;overflow:clip}
/* The header is two rows: this one, and the menu on its own line under it. So the
   nav is a sibling of .kcb-header__inner rather than something inside it, and it is
   deliberately full bleed, letting its own top hairline run the whole width of the
   page while the list inside it lines up with the shell. */
.kcb-nav{display:block}
.kcb-nav-list{display:flex;align-items:center;gap:clamp(1rem,2vw,1.7rem);list-style:none;padding:0;margin:0}
.kcb-nav-list>li{position:relative;display:flex;align-items:center;gap:.1rem}
.kcb-nav-list>li>a{position:relative;display:inline-flex;align-items:center;padding:.45rem 0;font-size:.875rem;font-weight:620;line-height:1.2;color:var(--kcb-muted);text-decoration:none;white-space:nowrap;transition:color var(--kcb-dur-fast) ease}
/* A hairline that grows out from the centre. left/right are animated instead of a
   scaleX transform so the rule stays exactly 1.5px tall at every point in the
   animation rather than being squashed along with the box. */
.kcb-nav-list>li>a::after{content:"";position:absolute;left:50%;right:50%;bottom:.05rem;height:1.5px;border-radius:2px;background:currentColor;transition:left var(--kcb-dur-fast) var(--kcb-ease),right var(--kcb-dur-fast) var(--kcb-ease)}
.kcb-nav-list>li>a:hover,.kcb-nav-list>li>a:focus-visible{color:var(--kcb-ink);text-decoration:none}
.kcb-nav-list>li>a:hover::after,.kcb-nav-list>li>a:focus-visible::after{left:0;right:0}
/* The open page keeps its underline. It is the only thing in the header that
   tells the visitor where they already are. */
.kcb-nav-list>.current-menu-item>a,.kcb-nav-list>.current-menu-ancestor>a,.kcb-nav-list>.current_page_item>a,.kcb-nav-list>.current_page_parent>a{color:var(--kcb-ink)}
.kcb-nav-list>.current-menu-item>a::after,.kcb-nav-list>.current-menu-ancestor>a::after,.kcb-nav-list>.current_page_item>a::after,.kcb-nav-list>.current_page_parent>a::after{left:0;right:0}

/* --- Dropdown --------------------------------------------------------------
   The parent stays a real link to its own page; this button is the disclosure
   beside it, and the only element that owns aria-expanded. Both CSS :hover and
   the script in assets/js/theme.js can open the panel, and the script mirrors
   aria-expanded onto the hover path so the two never disagree. Hover is kept as
   the base path deliberately: with JavaScript unavailable it is the only way the
   collection pages stay reachable from the header. */
.kcb-nav-item__toggle{display:inline-grid;place-items:center;flex:none;width:1.4rem;height:1.4rem;padding:0;border:0;border-radius:50%;background:transparent;color:var(--kcb-muted);cursor:pointer;transition:background-color var(--kcb-dur-fast) ease,color var(--kcb-dur-fast) ease}
.kcb-nav-item__toggle:hover{background:var(--kcb-surface);color:var(--kcb-ink)}
.kcb-nav-item__chevron{display:block;width:7px;height:7px;border-right:1.6px solid currentColor;border-bottom:1.6px solid currentColor;transform:translateY(-2px) rotate(45deg);transition:transform var(--kcb-dur-fast) ease}
.kcb-nav-item__toggle[aria-expanded="true"] .kcb-nav-item__chevron{transform:translateY(1px) rotate(225deg)}
.kcb-subnav{position:absolute;top:calc(100% + .6rem);left:-.85rem;z-index:5;min-width:262px;padding:.5rem;margin:0;list-style:none;background:#fff;border:1px solid var(--kcb-border);border-radius:16px;box-shadow:0 22px 55px rgba(32,33,31,.13);opacity:0;visibility:hidden;transform:translateY(-6px);transition:opacity var(--kcb-dur-fast) ease,transform var(--kcb-dur-fast) ease,visibility var(--kcb-dur-fast)}
/* Bridges the gap between the bar and the panel so crossing it with the pointer
   does not read as leaving the menu. */
.kcb-subnav::before{content:"";position:absolute;left:0;right:0;top:-.6rem;height:.6rem}
/* A 262px panel hanging off a label near the right edge of the header runs past the
   edge of the document and adds a horizontal scrollbar to the whole page, even while
   the panel is shut: a hidden absolutely-positioned box still counts toward
   scrollWidth. The last three items open theirs to the left instead, which is also
   where a visitor's eye already is at that end of the bar. Blog has no panel; Events
   and Free Printables do, and Events is the one that overflowed around 1265px. */
@media(min-width:960px){
	.kcb-nav-list>li:nth-last-child(-n+3)>.kcb-subnav{left:auto;right:-.85rem}
}
.kcb-nav-list>li.is-open>.kcb-subnav{opacity:1;visibility:visible;transform:none}
/* The no-JS fallback, and only that. assets/js/theme.js adds .kcb-js to <html> as
   its first act, so wherever the script runs the panel opens on .is-open alone and
   the script owns hover as well. Two mechanisms both able to open it is how
   aria-expanded ends up describing a panel that is already on screen. Without the
   script, :hover and :focus-within are the only way the collection pages stay
   reachable from the header, so they stay. */
@media(hover:hover) and (min-width:960px){
	html:not(.kcb-js) .kcb-nav-list>li:hover>.kcb-subnav,html:not(.kcb-js) .kcb-nav-list>li:focus-within>.kcb-subnav{opacity:1;visibility:visible;transform:none}
}
.kcb-subnav a{display:block;padding:.62rem .75rem;border-radius:10px;font-size:.9rem;font-weight:600;line-height:1.35;color:var(--kcb-ink);text-decoration:none;transition:background-color var(--kcb-dur-fast) ease}
.kcb-subnav a:hover{background:var(--kcb-surface);text-decoration:none}
.kcb-subnav .current-menu-item>a,.kcb-subnav .current_page_item>a{background:var(--kcb-surface)}
/* Activity Packs lives in the Shop dropdown and brings its own subcategories, so the
   menu has a third level. Depth two renders as an indented group inside the panel that
   is already open, never as a second flyout: only depth-zero items get a disclosure
   button, so a nested panel that started hidden would have nothing able to open it.
   visibility inherits rather than being forced visible, because forcing it would leak
   the nested list out of a closed parent, which is the one thing hidden has to mean. */
.kcb-subnav .kcb-subnav{position:static;z-index:auto;min-width:0;margin:.1rem 0 .35rem;padding:0 0 0 .9rem;border:0;border-left:1px solid var(--kcb-border);border-radius:0;background:transparent;box-shadow:none;opacity:1;visibility:inherit;transform:none;transition:none}
.kcb-subnav .kcb-subnav::before{display:none}
.kcb-subnav .kcb-subnav a{padding:.42rem .6rem;font-size:.84rem;font-weight:600;color:var(--kcb-muted)}
.kcb-subnav .kcb-subnav a:hover{color:var(--kcb-ink)}

/* Pinned to the right of the first row, with the toggle after it on a phone. The auto
   margin lives here rather than on the toggle so the row still reads brand-left,
   controls-right when WooCommerce is inactive and there is no basket to show. */
.kcb-header__actions{display:flex;align-items:center;gap:1.1rem;margin-left:auto}
.kcb-kicker-link{padding:.4rem 0;border-bottom:1.5px solid rgba(32,33,31,.22);font-size:.82rem;font-weight:680;color:var(--kcb-muted);text-decoration:none;white-space:nowrap;transition:color var(--kcb-dur-fast) ease,border-color var(--kcb-dur-fast) ease}
.kcb-kicker-link:hover{border-bottom-color:var(--kcb-ink);color:var(--kcb-ink);text-decoration:none}
.kcb-cart-link{display:inline-flex;align-items:center;gap:.45rem;padding:.45rem 0;font-size:.86rem;font-weight:640;color:var(--kcb-ink);text-decoration:none;white-space:nowrap;transition:opacity var(--kcb-dur-fast) ease}
.kcb-cart-link:hover{opacity:.68;text-decoration:none}
.kcb-cart-link__icon{display:inline-grid;place-items:center;line-height:0}
.kcb-cart-count{display:inline-grid;place-items:center;min-width:1.3rem;height:1.3rem;padding:0 .3rem;border:1px solid var(--kcb-border);border-radius:999px;background:var(--kcb-surface);font-size:.7rem;font-weight:750;line-height:1}
/* The first row holds four things, so nothing on it is ever short of room and the
   labels can all stay. min-width:0 stays on the nav and its list because the list is
   a row of nowrap labels: without it flex refuses to shrink the box, and the row hangs
   off the right edge of the document instead of settling inside the shell. */
.kcb-nav,.kcb-nav-list{min-width:0}
/* --- The second row --------------------------------------------------------
   Measured, not guessed: the nine labels with their disclosure chevrons and gaps need
   about 1005px, and on the first row they were left 772px once the brand and the
   basket had taken theirs, which is why they printed over each other. On their own
   row they have the full 1200px shell, so all nine show at every desktop width with
   nothing hidden. space-between spreads them from the brand's left edge to the call to
   action's right edge, so the row reads as one deliberate band rather than a cluster
   drifting left. Below 1200 the shell is the viewport, so the type steps down a
   notch and the gaps tighten to keep the whole set on one line down to 960. */
@media(min-width:960px){
	.kcb-header__inner{gap:2rem}
	.kcb-nav{border-top:1px solid rgba(32,33,31,.07)}
	.kcb-nav-list{width:min(calc(100% - 40px),var(--kcb-shell));margin-inline:auto;justify-content:space-between;gap:1rem}
	.kcb-nav-list>li>a{padding:.62rem 0}
}
@media(min-width:960px) and (max-width:1199.98px){
	.kcb-nav-list{gap:.4rem}
	.kcb-nav-list>li>a{font-size:.82rem}
	.kcb-nav-item__toggle{width:1.2rem;height:1.2rem}
}
.kcb-menu-toggle{display:none;align-items:center;gap:.55rem;min-height:44px;padding:.5rem .8rem;border:1px solid var(--kcb-border);border-radius:12px;background:#fff;color:inherit;font-size:.82rem;font-weight:720}
.kcb-menu-toggle__icon{display:inline-block;width:20px;height:12px;border-top:2px solid currentColor;border-bottom:2px solid currentColor}
.kcb-button,.wp-element-button{display:inline-flex;justify-content:center;align-items:center;min-height:48px;padding:.72rem 1.2rem;border:2px solid var(--kcb-ink);border-radius:12px;background:var(--kcb-ink);color:#fff!important;text-decoration:none!important;font-weight:760;line-height:1.1;cursor:pointer;transition:transform var(--kcb-dur-fast) ease,background-color var(--kcb-dur-fast) ease,color var(--kcb-dur-fast) ease}
.kcb-button:hover,.wp-element-button:hover{transform:translateY(-1px)}
.kcb-button--small{min-height:42px;padding:.58rem .9rem;font-size:.88rem}
.kcb-button--secondary{background:transparent;color:var(--kcb-ink)!important}
.kcb-button--light{background:#fff;border-color:#fff;color:var(--kcb-ink)!important}
.kcb-button--outline-light{background:transparent;border-color:#fff;color:#fff!important}
.kcb-button--playful{gap:.8rem;box-shadow:6px 6px 0 var(--kcb-coral)}
.kcb-button--playful:hover{transform:translate(2px,2px);box-shadow:4px 4px 0 var(--kcb-coral)}
.kcb-text-link{font-weight:760;text-decoration:underline}
.kcb-actions{display:flex;flex-wrap:wrap;gap:.8rem;align-items:center}
.kcb-eyebrow{margin:0 0 1rem;font-size:.76rem;line-height:1.3;font-weight:850;letter-spacing:.13em;text-transform:uppercase}
.kcb-lead{font-size:clamp(1.1rem,2.1vw,1.3rem);line-height:1.5;color:var(--kcb-muted)}
.kcb-microcopy{margin:.9rem 0 0;color:var(--kcb-muted);font-size:.9rem}
.kcb-hero{overflow:hidden;padding:clamp(4rem,9vw,8rem) 0}
.kcb-hero__grid{display:grid;grid-template-columns:minmax(0,.9fr) minmax(420px,1.1fr);gap:clamp(3rem,8vw,7rem);align-items:center}
.kcb-hero__copy{max-width:650px}
.kcb-hero__copy h1{max-width:11ch}
.kcb-hero__copy .kcb-lead{max-width:58ch}
.kcb-hero-art{position:relative;min-height:520px;display:grid;place-items:center}
.kcb-paper-stack{position:relative;width:min(100%,430px);height:480px}
.kcb-paper{position:absolute;inset:35px 20px;background:#fff;border:1px solid var(--kcb-border);box-shadow:var(--kcb-shadow)}
.kcb-paper--back{transform:rotate(-8deg) translate(-25px,5px);background:#f2eadb}
.kcb-paper--middle{transform:rotate(6deg) translate(26px,7px);background:#fff9e7}
.kcb-paper--front{display:flex;flex-direction:column;justify-content:space-between;padding:2rem;transform:rotate(-1deg)}
.kcb-paper__kicker{font-size:.72rem;font-weight:850;letter-spacing:.1em}
.kcb-paper__drawing{display:flex;align-items:flex-end;justify-content:center;gap:1rem;height:180px}
.kcb-paper__drawing span{display:block;width:70px;border:3px solid var(--kcb-ink);border-radius:50% 50% 42% 42%}
/* Each color-mix() is preceded by the resolved value so browsers without
   color-mix() support get the intended colour instead of dropping the
   declaration and falling back to transparent. */
.kcb-paper__drawing span:nth-child(1){height:95px;background:#FADCD8;background:color-mix(in srgb,var(--kcb-coral) 24%,white)}
.kcb-paper__drawing span:nth-child(2){height:145px;background:#F9EDD0;background:color-mix(in srgb,var(--kcb-yellow) 26%,white)}
.kcb-paper__drawing span:nth-child(3){height:115px;background:#DFEEF4;background:color-mix(in srgb,var(--kcb-sky) 24%,white)}
.kcb-paper--front strong{font-size:1.55rem;letter-spacing:-.03em}
.kcb-pencil{position:absolute;width:15px;height:180px;border:2px solid var(--kcb-ink);border-radius:4px;background:var(--kcb-coral);transform:rotate(35deg)}
.kcb-pencil--one{right:10%;bottom:8%}
.kcb-pencil--two{right:18%;bottom:2%;background:var(--kcb-sky);transform:rotate(47deg)}
.kcb-section-heading{max-width:780px;margin-bottom:2.5rem}
.kcb-section-heading--split{display:flex;align-items:flex-end;justify-content:space-between;gap:2rem;max-width:none}
.kcb-section-heading--split>div{max-width:780px}
.kcb-category-nav{padding-top:1rem}
.kcb-category-grid{display:grid;grid-template-columns:repeat(3,1fr);border-top:1px solid var(--kcb-border);border-left:1px solid var(--kcb-border)}
.kcb-category-link{display:flex;align-items:center;justify-content:space-between;gap:1rem;min-height:122px;padding:1.5rem;border-right:1px solid var(--kcb-border);border-bottom:1px solid var(--kcb-border);font-weight:780;font-size:1.1rem;text-decoration:none;transition:background-color var(--kcb-dur-fast) ease}
.kcb-category-link:hover{background:var(--kcb-surface)}
.kcb-category-link--coral:hover{background:#FBE8E5;background:color-mix(in srgb,var(--kcb-coral) 16%,white)}
.kcb-category-link--sky:hover{background:#E7F2F7;background:color-mix(in srgb,var(--kcb-sky) 18%,white)}
.kcb-category-link--yellow:hover{background:#FAF1DB;background:color-mix(in srgb,var(--kcb-yellow) 20%,white)}
.kcb-category-link--green:hover{background:#E8F1EA;background:color-mix(in srgb,var(--kcb-green) 20%,white)}
.kcb-category-link--ink:hover{background:var(--kcb-ink);color:#fff}
.kcb-featured{background:#fff}
.kcb-moments{background:var(--kcb-surface)}
.kcb-moments__grid{display:grid;grid-template-columns:.8fr 1.2fr;gap:clamp(3rem,9vw,8rem)}
.kcb-moments__intro{position:sticky;top:120px;align-self:start}
.kcb-moments__intro p:last-child{color:var(--kcb-muted)}
.kcb-moments__list{border-top:1px solid var(--kcb-border)}
.kcb-moments__list article{display:grid;grid-template-columns:52px 1fr;gap:1.2rem;padding:1.8rem 0;border-bottom:1px solid var(--kcb-border)}
.kcb-moments__list article>span{font-size:.76rem;font-weight:850;color:var(--kcb-muted)}
.kcb-moments__list article p{margin:0;color:var(--kcb-muted)}
.kcb-steps{display:grid;grid-template-columns:repeat(3,1fr);gap:0;list-style:none;padding:0;margin:0;border-top:1px solid var(--kcb-border)}
.kcb-steps li{display:grid;grid-template-columns:52px 1fr;gap:1rem;padding:2rem 2rem 1rem 0;border-right:1px solid var(--kcb-border)}
.kcb-steps li+li{padding-left:2rem}
.kcb-steps li:last-child{border-right:0}
.kcb-steps>li>span{display:grid;place-items:center;width:40px;height:40px;border-radius:50%;background:var(--kcb-ink);color:#fff;font-weight:850}
.kcb-steps p{color:var(--kcb-muted)}
.kcb-freebie{padding:var(--kcb-section-y-loose) 0;background:var(--kcb-yellow)}
.kcb-freebie__grid{display:grid;grid-template-columns:1fr 1fr;align-items:center;gap:clamp(2.5rem,8vw,6rem)}
.kcb-freebie__action{max-width:520px}
.kcb-admin-hint{padding:.8rem 1rem;border:1px dashed currentColor;font-size:.82rem;background:rgba(255,255,255,.4)}
.kcb-social__grid{display:grid;grid-template-columns:1fr .85fr;align-items:end;gap:4rem}
.kcb-social-links{display:flex;flex-wrap:wrap;gap:.7rem}
.kcb-social-links a{font-weight:750;text-decoration:underline}
.kcb-social-links--large a{display:flex;align-items:center;justify-content:space-between;min-width:calc(50% - .5rem);padding:1rem;border-top:1px solid var(--kcb-border);text-decoration:none}
.kcb-final-cta{padding:clamp(4rem,8vw,6rem) 0;background:var(--kcb-ink);color:#fff}
.kcb-final-cta__inner{display:grid;grid-template-columns:1fr auto;gap:3rem;align-items:end}
.kcb-final-cta__inner>div:first-child{max-width:750px}
.kcb-footer{background:#11120f;color:#fff;padding:4rem 0 1.5rem}
.kcb-footer__grid{display:grid;grid-template-columns:1.5fr repeat(3,1fr);gap:3rem}
.kcb-footer h2{font-size:.82rem;letter-spacing:.08em;text-transform:uppercase}
.kcb-footer ul{list-style:none;padding:0;margin:0}
.kcb-footer li{margin:.55rem 0}
.kcb-footer a{color:#fff}
.kcb-footer__brand p{max-width:34ch;color:#c8c9c5}
.kcb-social-links--footer{flex-direction:column}
.kcb-footer__bottom{display:flex;justify-content:space-between;gap:2rem;margin-top:3rem;padding-top:1.2rem;border-top:1px solid rgba(255,255,255,.18);font-size:.82rem;color:#c8c9c5}
.kcb-footer__bottom p{margin:0}
.kcb-footer__legal{display:flex;gap:1rem}
/* footer.php emits .kcb-footer--v3 and the watermark on every template. */
.kcb-footer--v3{position:relative;padding:5rem 0 1.4rem;background:#11120f;color:#fff;overflow:hidden}
.kcb-footer__headline{position:absolute;left:0;right:0;top:20px;display:flex;justify-content:center;font-size:clamp(4rem,14vw,12rem);font-weight:900;letter-spacing:-.08em;line-height:.8;color:rgba(255,255,255,.06);pointer-events:none;user-select:none}
.kcb-footer--v3 .kcb-footer__grid{position:relative;z-index:1;grid-template-columns:1.5fr 1fr 1fr 1fr}
/* Suppresses the second brand wordmark under the footer logo. */
.kcb-footer--v3 .kcb-brand-lockup__text{display:none}
.kcb-footer--v3 .kcb-footer__brand p{max-width:36ch;color:#d1d2cf}
.kcb-footer--v3 .kcb-footer__bottom{position:relative;z-index:1}
.kcb-cookie-settings{appearance:none;border:0;background:transparent;color:inherit;padding:0;font:inherit;text-decoration:underline;cursor:pointer}
.kcb-cookie-banner[hidden]{display:none}.kcb-cookie-banner{position:fixed;z-index:99999;left:50%;bottom:1rem;transform:translateX(-50%);width:min(calc(100% - 2rem),920px);display:flex;align-items:center;justify-content:space-between;gap:1.5rem;padding:1.2rem 1.35rem;border:1px solid var(--kcb-border);border-radius:14px;background:#fff;box-shadow:0 18px 60px rgba(10,28,54,.18)}
.kcb-cookie-banner p{margin:.35rem 0 0;color:var(--kcb-muted);font-size:.9rem}.kcb-cookie-banner__actions{display:flex;gap:.6rem;flex:none}.kcb-cookie-banner .kcb-button{min-height:42px;padding:.65rem 1rem}
.kcb-blog-categories{display:flex;flex-wrap:wrap;gap:.6rem;padding-top:2rem}.kcb-blog-categories a{padding:.55rem .85rem;border:1px solid var(--kcb-border);border-radius:999px;text-decoration:none;font-size:.85rem;font-weight:750;background:#fff}
.kcb-page-hero{padding:clamp(4rem,8vw,7rem) 0 clamp(2.5rem,5vw,4rem);border-bottom:1px solid var(--kcb-border)}
.kcb-page-hero h1{font-size:clamp(2.5rem,6vw,4.2rem)}
.kcb-entry-content{padding-top:3rem;padding-bottom:5rem}
.kcb-entry-content>*{max-width:100%}
.kcb-entry-content h2,.kcb-entry-content h3{margin-top:1.8em}
.kcb-entry-content a{text-decoration:underline}
.kcb-entry-content img{border-radius:10px}
.kcb-landing-grid{display:grid;grid-template-columns:1fr .8fr;gap:4rem;align-items:start}
.kcb-page-hero--freebie{background:var(--kcb-yellow)}
.kcb-freebie-card{background:#fff;padding:clamp(1.5rem,4vw,2.5rem);border:1px solid var(--kcb-ink);box-shadow:8px 8px 0 var(--kcb-ink)}
.kcb-faq{border-top:1px solid var(--kcb-border)}
.kcb-faq details{border-bottom:1px solid var(--kcb-border);padding:0}
.kcb-faq summary{cursor:pointer;font-weight:780;font-size:1.08rem;padding:1.3rem 0}
.kcb-faq details p{padding-bottom:1.2rem;color:var(--kcb-muted)}
.kcb-security-note{padding:1rem 1.2rem;background:var(--kcb-surface);border-left:4px solid var(--kcb-yellow)}
.kcb-post-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:2rem}
.kcb-post-card{border-top:1px solid var(--kcb-border);padding-top:1rem}
.kcb-post-card__media{display:block;aspect-ratio:4/3;background:var(--kcb-surface);overflow:hidden;text-decoration:none}
.kcb-post-card__media img{width:100%;height:100%;object-fit:cover}
.kcb-post-card__placeholder{display:block;width:100%;height:100%;background:linear-gradient(135deg,var(--kcb-surface),#fff)}
.kcb-post-card__body{padding-top:1rem}
.kcb-post-card h2{font-size:1.35rem}
.kcb-post-card h2 a{text-decoration:none}
.kcb-post-card p{color:var(--kcb-muted)}
.kcb-post-card__meta{font-size:.78rem;font-weight:750}
.kcb-post-card--featured{grid-column:1/-1;display:grid;grid-template-columns:minmax(0,1.35fr) minmax(280px,.65fr);gap:2rem;padding:1rem;border:1px solid var(--kcb-border);border-radius:12px;background:#fff}.kcb-post-card--featured .kcb-post-card__media{aspect-ratio:16/9}.kcb-post-card--featured .kcb-post-card__body{align-self:center;padding:1rem}.kcb-post-card--featured h2{font-size:clamp(1.8rem,4vw,3rem)}
.kcb-article__image{padding-top:2rem}
.kcb-article__image img{display:block;width:100%;max-height:700px;object-fit:cover}
.kcb-post-meta{display:flex;flex-wrap:wrap;gap:.45rem 1rem;align-items:center;color:var(--kcb-muted);font-size:.9rem}
.kcb-post-meta a,.kcb-post-card__meta a{font-weight:700;text-underline-offset:.2em}
.kcb-article__tags{display:flex;flex-wrap:wrap;gap:.65rem;margin-top:3rem;padding-top:1.25rem;border-top:1px solid var(--kcb-border)}
.kcb-article__tags a{display:inline-flex;padding:.35rem .7rem;border:1px solid var(--kcb-border);border-radius:999px;text-decoration:none;font-size:.85rem;font-weight:700}
.post-navigation{margin-top:3rem;padding-top:2rem;border-top:1px solid var(--kcb-border)}
.post-navigation .nav-links{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1rem}
.post-navigation .nav-next{text-align:right}
.post-navigation a{display:flex;flex-direction:column;min-height:100%;padding:1rem;border:1px solid var(--kcb-border);border-radius:var(--kcb-radius);text-decoration:none}
.kcb-post-nav__label{margin-bottom:.35rem;color:var(--kcb-muted);font-size:.72rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase}
.kcb-article-tools{display:flex;flex-wrap:wrap;gap:.7rem 1rem;align-items:center;margin-top:3rem;padding:1rem 0;border-top:1px solid var(--kcb-border);border-bottom:1px solid var(--kcb-border)}.kcb-article-tools a{font-weight:750}.kcb-related-posts{padding-top:4rem;padding-bottom:5rem}.kcb-related-posts>h2{max-width:18ch;margin-bottom:2rem}

/* --- Comments --------------------------------------------------------------
   inc/setup.php asks WordPress for html5 comment markup, so the selectors below
   are the ones the core walker and comment_form() actually emit. The theme had
   no comments.php and no rule here at all, so a thread would have rendered as
   an unstyled nested list. */
.kcb-comments{padding-bottom:5rem}
.kcb-comments__title{font-size:clamp(1.6rem,3vw,2.1rem);margin-bottom:1.75rem}
.kcb-comments__closed{color:var(--kcb-muted)}
.kcb-comment-list,.kcb-comment-list .children{list-style:none;padding-left:0}
.kcb-comment-list{margin:0 0 3rem}
/* Replies stay visibly attached to their parent instead of relying on indent
   alone, which collapses to almost nothing on a phone. */
.kcb-comment-list .children{margin:1.25rem 0 0;padding-left:clamp(.9rem,4vw,2.25rem);border-left:2px solid var(--kcb-border)}
.kcb-comment-list li{margin-top:1.25rem}
.kcb-comment-list>li:first-child{margin-top:0}
.comment-body{padding:1.25rem 1.35rem;border:1px solid var(--kcb-border);border-radius:var(--kcb-radius);background:#fff}
.comment-meta{display:flex;flex-wrap:wrap;gap:.3rem .9rem;align-items:center;margin-bottom:.75rem}
.comment-author{display:flex;align-items:center;gap:.6rem;font-weight:750}
.comment-author img{border-radius:50%}
/* "says:" is there for screen readers and reads as noise on screen. */
.comment-author .says{border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}
.comment-metadata{color:var(--kcb-muted);font-size:.85rem}
.comment-metadata a{text-decoration:none}
.comment-content>*:last-child{margin-bottom:0}
/* Core puts this inside the flex .comment-meta row, where a bare display:block
   does nothing. flex-basis gives the one message that reports state its own line. */
.comment-awaiting-moderation{flex:0 0 100%;margin:.15rem 0 0;color:var(--kcb-muted);font-size:.85rem;font-weight:750}
.comment-body .reply{margin-top:.85rem}
.comment-body .reply a{font-weight:750;font-size:.88rem}
.bypostauthor>.comment-body{border-color:var(--kcb-ink)}
.comment-navigation{margin-bottom:2.5rem}
.comment-respond{padding-top:2.5rem;border-top:1px solid var(--kcb-border)}
.comment-reply-title{font-size:clamp(1.45rem,3vw,1.9rem)}
/* The cancel-reply link core tucks inside the heading. */
.comment-reply-title small{display:block;margin-top:.5rem;font-size:.9rem;font-weight:650}
.kcb-comment-form__notes,.comment-form .comment-notes{color:var(--kcb-muted);font-size:.92rem}
.kcb-comment-form label{display:block;margin-bottom:.35rem}
.kcb-comment-form input[type="text"],.kcb-comment-form input[type="email"],.kcb-comment-form input[type="url"],.kcb-comment-form textarea{width:100%}
.kcb-comment-form .comment-form-cookies-consent{display:flex;gap:.6rem;align-items:flex-start}
.kcb-comment-form .comment-form-cookies-consent input{flex:none;margin-top:.45rem}
.kcb-comment-form .comment-form-cookies-consent label{margin:0;font-weight:650}
.kcb-empty-state{padding:3rem 0;border-top:1px solid var(--kcb-border)}
.kcb-empty-state p{color:var(--kcb-muted)}
.kcb-not-found{display:grid;align-items:center;min-height:65vh;padding:5rem 0}
.kcb-search-form{margin-bottom:3rem;max-width:680px}
.kcb-search-form label{display:block;font-weight:750;margin-bottom:.45rem}
.kcb-search-form__row{display:flex;gap:.7rem}
.kcb-search-form input{flex:1;min-height:48px;border:1px solid var(--kcb-border);border-radius:10px;background:#fff;padding:.65rem .85rem;color:var(--kcb-ink)}
input[type="text"],input[type="email"],input[type="tel"],input[type="url"],input[type="password"],input[type="number"],input[type="search"],textarea,select{max-width:100%;border:1px solid #bcb8ae;border-radius:10px;background:#fff;color:var(--kcb-ink);padding:.72rem .82rem}
textarea{min-height:150px;resize:vertical}
label{font-weight:650}
.navigation.pagination{margin-top:3rem}
.nav-links{display:flex;gap:.5rem;flex-wrap:wrap}
.page-numbers{display:inline-grid;place-items:center;min-width:42px;height:42px;border:1px solid var(--kcb-border);text-decoration:none}
.page-numbers.current{background:var(--kcb-ink);color:#fff}
/* .98 rather than a whole pixel: a viewport can land on 959.5 after zoom or a
   fractional device ratio, and max-width:959px and min-width:960px both miss it. The
   header then rendered its untiered desktop layout with no room for it, which is 400px
   of horizontal overflow from a gap one pixel wide. */
@media(max-width:959.98px){
	:root{--kcb-header-h:74px}
	.kcb-header__inner{gap:1rem}
	.kcb-menu-toggle{display:inline-flex}
	.kcb-nav{display:none;position:absolute;left:0;right:0;top:100%;min-height:calc(100vh - var(--kcb-header-h));max-height:calc(100vh - var(--kcb-header-h));overflow-y:auto;background:var(--kcb-paper);padding:1.25rem 20px 3rem;align-items:stretch;justify-content:flex-start;flex-direction:column;border-top:1px solid var(--kcb-border)}
	.kcb-nav.is-open{display:flex}
	.kcb-nav-list{display:flex;flex-direction:column;align-items:stretch;gap:0}
	.kcb-nav-list>li{display:flex;flex-wrap:wrap;align-items:center;gap:0;border-bottom:1px solid var(--kcb-border)}
	.kcb-nav-list>li>a{flex:1;padding:1rem 0;font-size:1.05rem;font-weight:700;color:var(--kcb-ink)}
	.kcb-nav-list>li>a::after{display:none}
	/* A 44px tap target for the accordion, sitting beside the link rather than
	   swallowing it, so opening the group and going to the page stay separate. */
	.kcb-nav-item__toggle{width:44px;height:44px;border-radius:12px}
	.kcb-nav-item__chevron{width:9px;height:9px}
	/* display:none rather than visibility:hidden, so a closed group's links stay
	   out of the drawer's focus trap in assets/js/theme.js, which filters on
	   getClientRects(). */
	.kcb-subnav{display:none;position:static;flex:0 0 100%;min-width:0;margin:0 0 .9rem;padding:.2rem 0 .2rem .85rem;border:0;border-left:2px solid var(--kcb-border);border-radius:0;background:transparent;box-shadow:none;opacity:1;visibility:visible;transform:none;transition:none}
	.kcb-nav-list>li.is-open>.kcb-subnav{display:block}
	/* Depth two has no toggle of its own, so in the drawer it shows with its parent
	   group. A closed group is display:none, which takes its nested list with it, so
	   this never puts Activity Packs' subcategories in the focus trap while Shop is
	   shut. margin-bottom is dropped: the group's own left rule already ends the list. */
	.kcb-subnav .kcb-subnav{display:block;margin:0 0 .35rem;padding:.1rem 0 .1rem .7rem;border-left-width:1px}
	.kcb-subnav .kcb-subnav a{padding:.62rem .6rem;font-size:.92rem}
	.kcb-subnav::before{display:none}
	.kcb-subnav a{padding:.72rem .6rem;font-size:1rem}
	/* The drawer holds the menu and nothing else now. Shop and Free Printables are
	   both in it as menu items, so the two links that used to sit at the bottom of it
	   were saying the same thing twice; the basket they sat with has moved up to the
	   first row, where it is on screen without opening anything. The word beside the
	   icon goes, not the accessible name, because the row is 354px wide on a phone and
	   the brand has first claim on it. */
	.kcb-header__actions .kcb-kicker-link,.kcb-header__actions .kcb-button{display:none}
	.kcb-cart-link{gap:.4rem}
	.kcb-cart-link__label{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);border:0}
	.kcb-hero__grid{grid-template-columns:1fr;gap:2rem}
	.kcb-hero-art{min-height:430px}
	.kcb-paper-stack{height:420px;width:min(88%,390px)}
	.kcb-category-grid{grid-template-columns:repeat(2,1fr)}
	.kcb-moments__grid,.kcb-freebie__grid,.kcb-social__grid,.kcb-landing-grid{grid-template-columns:1fr}
	.kcb-moments__intro{position:static}
	.kcb-footer__grid,.kcb-footer--v3 .kcb-footer__grid{grid-template-columns:1.3fr 1fr 1fr}
	.kcb-footer__grid>div:last-child,.kcb-footer--v3 .kcb-footer__grid>div:last-child{grid-column:2/4}
	.kcb-post-grid{grid-template-columns:repeat(2,1fr)}
}
@media(max-width:680px){
	.kcb-cookie-banner{align-items:stretch;flex-direction:column}.kcb-cookie-banner__actions{display:grid;grid-template-columns:1fr 1fr}.kcb-post-card--featured{display:block;padding:0}.kcb-post-card--featured .kcb-post-card__body{padding:1.2rem}
	.kcb-brand{max-width:150px}
	.kcb-brand-lockup--header .custom-logo,
	.kcb-brand-lockup--header .kcb-brand-lockup__logo{height:var(--kcb-logo-height-mobile,46px);max-height:var(--kcb-logo-height-mobile,46px);max-width:var(--kcb-logo-max-width,190px)}
	.kcb-brand-lockup__text{font-size:.96rem}
	.elementor-location-header .elementor-widget-theme-site-logo img{max-height:64px}
	.kcb-shell{width:min(calc(100% - 36px),var(--kcb-shell))}
	/* There was a .kcb-section{padding:4rem 0} here. The clamp already bottoms
	   out at 4rem by 680px, so it changed nothing except to flatten the tight
	   and loose variants back to one value at exactly the width where the
	   difference in vertical space matters most. */
	.kcb-hero{padding:3.6rem 0 4.4rem}
	.kcb-hero-art{min-height:360px}
	.kcb-paper-stack{height:350px;width:88%}
	.kcb-paper{inset:28px 18px}
	.kcb-paper--front{padding:1.35rem}
	.kcb-paper__drawing{height:135px}
	.kcb-paper__drawing span{width:52px}
	.kcb-paper__drawing span:nth-child(1){height:70px}
	.kcb-paper__drawing span:nth-child(2){height:105px}
	.kcb-paper__drawing span:nth-child(3){height:82px}
	.kcb-pencil{height:130px}
	.kcb-actions{align-items:stretch;flex-direction:column}
	.kcb-actions .kcb-button{width:100%}
	.kcb-section-heading--split{align-items:flex-start;flex-direction:column}
	.kcb-category-grid{grid-template-columns:1fr}
	.kcb-category-link{min-height:92px}
	.kcb-steps{grid-template-columns:1fr}
	.kcb-steps li,.kcb-steps li+li{padding:1.4rem 0;border-right:0;border-bottom:1px solid var(--kcb-border)}
	.kcb-steps li:last-child{border-bottom:0}
	.kcb-final-cta__inner{grid-template-columns:1fr}
	.kcb-footer__headline{font-size:3.2rem;top:34px}
	.kcb-footer__grid,.kcb-footer--v3 .kcb-footer__grid{grid-template-columns:1fr 1fr;gap:2rem}
	.kcb-footer__brand,.kcb-footer--v3 .kcb-footer__brand{grid-column:1/-1}
	.kcb-footer__grid>div:last-child,.kcb-footer--v3 .kcb-footer__grid>div:last-child{grid-column:auto}
	.kcb-footer__bottom{flex-direction:column}
	.kcb-post-grid{grid-template-columns:1fr}
	.kcb-search-form__row{flex-direction:column}
	.post-navigation .nav-links{grid-template-columns:1fr}
	.post-navigation .nav-next{text-align:left}
}
@media(max-width:360px){
	body{font-size:16px}
	.kcb-shell{width:min(calc(100% - 28px),var(--kcb-shell))}
	/* Measured: at 360px the row has 315px and the brand, the basket and a toggle
	   with the word Menu on it want 321, so the button was hanging 6px into the
	   gutter. The word goes and the burger stays, which is what a phone reads as a
	   menu anyway. Hidden from sight only, so the button keeps its accessible name. */
	.kcb-header__inner{gap:.6rem}
	.kcb-menu-toggle__label{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);border:0}
	.kcb-footer__grid,.kcb-footer--v3 .kcb-footer__grid{grid-template-columns:1fr}
	.kcb-footer__brand,.kcb-footer__grid>div:last-child,
	.kcb-footer--v3 .kcb-footer__brand,.kcb-footer--v3 .kcb-footer__grid>div:last-child{grid-column:auto}
}
@media(prefers-reduced-motion:reduce){
	html{scroll-behavior:auto}
	*,*::before,*::after{scroll-behavior:auto!important;transition-duration:.01ms!important;animation-duration:.01ms!important;animation-iteration-count:1!important}
}
