/*
Theme Name: Katha Kutty
Theme URI: https://www.kathakutty.com
Author: Apple Story Club
Author URI: https://www.kathakutty.com
Description: Brand theme for Katha Kutty - a screen-free Malayalam storytelling app for children. A night-to-morning page: the hero is the hour the product is actually for, and the page lifts into daylight as you scroll. Live stories, pricing and the app's own intro video arrive through the "Katha Kutty Connect" plugin.
Version: 3.2.4
Requires at least: 6.0
Requires PHP: 7.4
Text Domain: katha-kutty
*/

/* ==========================================================================
   NIGHTFALL - the design idea, written down so the next person changing
   this file knows what they are keeping.

   Every children's app site is a bright cream page with an orange button.
   This one is not, because this product is not. Katha Kutty is audio, for
   the dark - bedtime, eyes closed, no screen. So the page starts at night
   and ends in the morning, and the scroll IS that transition: an ink-blue
   hero holding the app's own intro video like a lamp in a dark room, a
   category ribbon crossing the boundary, then daylight for the library and
   the practical sections, then night again for the download.

   The structure is not decoration. A parent reads the top of this page at
   9pm with a child who will not settle. The page should look like that
   moment.
   ========================================================================== */

:root {
    /* --- night --------------------------------------------------------- */
    --kk-night:        #14122B; /* the ink the hero sits on               */
    --kk-night-2:      #0B0A1A; /* deepest - footer, the bottom of a band */
    --kk-night-3:      #221F41; /* a raised surface on the night ground   */

    /* --- day ----------------------------------------------------------- */
    --kk-cream:        #FDF7EE; /* the morning ground                     */
    --kk-surface:      #FFFFFF;
    --kk-muted:        #F6EBDC; /* second surface, warmer than the ground */

    /* --- the palette ---------------------------------------------------
       Coral is the only saturated colour that appears at full strength on
       the light ground; gold belongs to the night. Keeping them apart is
       what stops the page reading as "orange website". */
    --kk-primary:      #EE6C4D;
    --kk-primary-dark: #C9503A;
    --kk-primary-light:#F7A791;
    --kk-gold:         #F6B93B;
    --kk-teal:         #3FA796;
    --kk-lavender:     #A390D4;
    --kk-green:        #57A773;

    /* --- text ----------------------------------------------------------
       The neutrals carry a violet bias rather than being true grey. It is
       a small thing and it is most of the difference between a palette
       that looks chosen and one that looks defaulted. */
    --kk-text:         #221E33;
    --kk-text-muted:   #625B75;
    --kk-text-light:   #F3EEF8;
    --kk-text-dim:     #A9A2BD;
    --kk-divider:      #EDE1D2;
    --kk-divider-dark: rgba(255, 255, 255, .12);

    --kk-radius:       22px;
    --kk-radius-sm:    14px;
    --kk-radius-lg:    34px;
    --kk-radius-pill:  999px;

    --kk-shadow:       0 18px 42px -18px rgba(34, 30, 51, .28);
    --kk-shadow-lg:    0 34px 80px -28px rgba(34, 30, 51, .38);
    --kk-shadow-lift:  0 26px 58px -22px rgba(34, 30, 51, .42);
    --kk-glow:         0 0 90px -10px rgba(246, 185, 59, .45);

    --kk-max:          1180px;
    --kk-gutter:       clamp(18px, 5vw, 40px);

    /* A type scale, kept to. Nothing on this site picks a font size that
       is not one of these. */
    --kk-t-xs:  .78rem;
    --kk-t-sm:  .92rem;
    --kk-t-md:  1.02rem;
    --kk-t-lg:  1.16rem;
    --kk-t-xl:  clamp(1.4rem, 1.1rem + 1.1vw, 1.85rem);
    --kk-t-2xl: clamp(1.85rem, 1.3rem + 2.4vw, 2.9rem);
    --kk-t-3xl: clamp(2.4rem, 1.5rem + 4vw, 4.1rem);

    --kk-display: 'Fraunces', ui-serif, Georgia, 'Times New Roman', serif;
    --kk-body: 'Figtree', 'Noto Sans Malayalam', -apple-system, BlinkMacSystemFont,
               'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
    --kk-mal: 'Noto Sans Malayalam', 'Figtree', sans-serif;

    color-scheme: light;
}

/* ==========================================================================
   Reset and base
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
    margin: 0;
    background: var(--kk-cream);
    color: var(--kk-text);
    font-family: var(--kk-body);
    font-size: var(--kk-t-md);
    line-height: 1.65;
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
}

img, svg, video { max-width: 100%; display: block; }
img, video { height: auto; }

/* The browser's own stylesheet gives <figure> a 40px side margin. In a
   narrow grid column - the cover tiles inside the phone mockups - that is
   most of the column, and the artwork collapses to a dot. */
figure { margin: 0; }

a { color: var(--kk-primary-dark); text-decoration-thickness: 1.5px; text-underline-offset: 3px; }
a:hover { color: var(--kk-primary); }

:focus-visible {
    outline: 3px solid var(--kk-gold);
    outline-offset: 3px;
    border-radius: 6px;
}

h1, h2, h3, h4 {
    font-family: var(--kk-display);
    font-weight: 600;
    line-height: 1.12;
    letter-spacing: -.015em;
    text-wrap: balance;
    margin: 0 0 .5em;
    /* Fraunces is variable. SOFT gives the letterforms their rounded,
       storybook quality; a touch of WONK keeps them from looking like a
       magazine masthead. */
    font-variation-settings: 'SOFT' 40, 'WONK' 1, 'opsz' 40;
}
h1 { font-size: var(--kk-t-3xl); font-weight: 700; }
h2 { font-size: var(--kk-t-2xl); }
h3 { font-size: var(--kk-t-xl); }
h4 { font-size: var(--kk-t-lg); }

p { margin: 0 0 1.1em; max-width: 68ch; }

::selection { background: var(--kk-gold); color: var(--kk-night); }

.kk-sr {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Malayalam runs inside otherwise-Latin text (the category ribbon). */
:lang(ml), .kk-ml { font-family: var(--kk-mal); }

/* ==========================================================================
   Layout primitives
   ========================================================================== */
.kk-container {
    width: 100%;
    max-width: var(--kk-max);
    margin-inline: auto;
    padding-inline: var(--kk-gutter);
}

.kk-section { position: relative; padding-block: clamp(60px, 8vw, 108px); }
.kk-section--tight { padding-block: clamp(40px, 5vw, 68px); }

.kk-section--muted { background: var(--kk-muted); }

.kk-section--night {
    background: var(--kk-night);
    color: var(--kk-text-light);
    overflow: hidden;
}
.kk-section--night h2,
.kk-section--night h3 { color: #fff; }
.kk-section--night p { color: var(--kk-text-dim); }

.kk-center { text-align: center; }
.kk-mx-auto { margin-inline: auto; }
.kk-mt-xl { margin-top: clamp(28px, 4vw, 48px); }
.kk-center-flex { display: flex; flex-wrap: wrap; gap: 14px; justify-content: center; }

.kk-sectionhead {
    max-width: 660px;
    margin: 0 auto clamp(32px, 5vw, 56px);
    text-align: center;
}
.kk-sectionhead p {
    color: var(--kk-text-muted);
    font-size: var(--kk-t-lg);
    margin-inline: auto;
}
.kk-section--night .kk-sectionhead p { color: var(--kk-text-dim); }

.kk-eyebrow {
    display: inline-block;
    font-family: var(--kk-body);
    font-size: var(--kk-t-xs);
    font-weight: 700;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--kk-primary-dark);
    background: rgba(238, 108, 77, .1);
    border-radius: 999px;
    padding: 7px 15px;
    margin-bottom: 16px;
}
.kk-eyebrow--light {
    color: var(--kk-gold);
    background: rgba(246, 185, 59, .13);
    border: 1px solid rgba(246, 185, 59, .3);
}

.kk-lede {
    font-size: var(--kk-t-lg);
    color: var(--kk-text-muted);
    line-height: 1.66;
}

/* ==========================================================================
   Buttons
   ========================================================================== */
.kk-btn {
    --btn-bg: var(--kk-primary);
    --btn-fg: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    font-family: var(--kk-body);
    font-weight: 700;
    font-size: var(--kk-t-md);
    line-height: 1;
    padding: 15px 26px;
    border-radius: 999px;
    border: 2px solid transparent;
    background: var(--btn-bg);
    color: var(--btn-fg);
    text-decoration: none;
    cursor: pointer;
    transition: transform .18s ease, box-shadow .18s ease, background-color .18s ease;
}
.kk-btn:hover { transform: translateY(-2px); color: var(--btn-fg); }
.kk-btn:active { transform: translateY(0); }

.kk-btn--primary {
    box-shadow: 0 12px 26px -10px rgba(238, 108, 77, .75);
}
.kk-btn--primary:hover { background: var(--kk-primary-dark); }

.kk-btn--ghost {
    --btn-bg: transparent;
    --btn-fg: #fff;
    border-color: rgba(255, 255, 255, .32);
    backdrop-filter: blur(6px);
}
.kk-btn--ghost:hover { border-color: rgba(255, 255, 255, .7); background: rgba(255, 255, 255, .08); }

.kk-btn--outline {
    --btn-bg: transparent;
    --btn-fg: var(--kk-primary-dark);
    border-color: rgba(238, 108, 77, .45);
}
.kk-btn--outline:hover { background: rgba(238, 108, 77, .08); border-color: var(--kk-primary); }

.kk-btn--lg { padding: 18px 34px; font-size: var(--kk-t-lg); }

/* ==========================================================================
   Header
   ========================================================================== */
.kk-header {
    /* FIXED, not sticky.
       Sticky keeps the header in normal flow, so it sat ABOVE the hero as a
       band of page background - which on this design meant a cream stripe
       across the top of a night sky. The header has to overlap the hero for
       the transparent-until-scrolled effect to mean anything, and only
       fixed (or absolute) takes it out of flow. The hero's generous top
       padding is what leaves room for it. */
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 60;
    background: transparent;
    transition: background-color .3s ease, box-shadow .3s ease, backdrop-filter .3s ease;
}

/* Interior pages have no hero to float over, so their content has to start
   below the header rather than underneath it. */
body:not(.home) #kk-main { padding-top: 74px; }
.kk-header__inner {
    display: flex;
    align-items: center;
    gap: 20px;
    min-height: 74px;
}
.kk-header.is-stuck {
    background: rgba(20, 18, 43, .82);
    backdrop-filter: blur(14px);
    box-shadow: 0 1px 0 rgba(255, 255, 255, .08);
}
/* Interior pages have no night hero above the fold, so the header there is
   solid from the first pixel rather than floating over cream text. */
body:not(.home) .kk-header {
    background: rgba(20, 18, 43, .96);
}

.kk-brand {
    display: inline-flex;
    align-items: center;
    gap: 11px;
    text-decoration: none;
    margin-right: auto;
}
.kk-brand img { max-height: 42px; width: auto; }
.kk-brand__name {
    font-family: var(--kk-display);
    font-weight: 700;
    font-size: 1.42rem;
    color: #fff;
    line-height: 1.05;
    letter-spacing: -.02em;
}
.kk-brand__by {
    display: block;
    font-family: var(--kk-body);
    font-size: .66rem;
    font-weight: 600;
    letter-spacing: .13em;
    text-transform: uppercase;
    color: var(--kk-gold);
}

.kk-menu {
    display: flex;
    align-items: center;
    gap: 4px;
    list-style: none;
    margin: 0;
    padding: 0;
}
.kk-menu a {
    display: block;
    padding: 9px 14px;
    border-radius: 999px;
    font-size: var(--kk-t-sm);
    font-weight: 600;
    color: rgba(255, 255, 255, .82);
    text-decoration: none;
    transition: background-color .18s ease, color .18s ease;
}
.kk-menu a:hover,
.kk-menu .current-menu-item > a {
    color: #fff;
    background: rgba(255, 255, 255, .1);
}
/* The download button exists twice in the markup: in the bar, and again
   inside the collapsible menu so phones still have one. Exactly one of the
   two is visible at any width. */
.kk-header__nav .kk-header__cta { display: none; }

.kk-menu .sub-menu {
    display: none;
    position: absolute;
    background: var(--kk-night-3);
    border-radius: var(--kk-radius-sm);
    padding: 8px;
    list-style: none;
    box-shadow: var(--kk-shadow-lg);
}
.kk-menu li:hover > .sub-menu { display: block; }

.kk-nav-toggle {
    display: none;
    width: 44px; height: 44px;
    border: 0;
    border-radius: 12px;
    background: rgba(255, 255, 255, .12);
    cursor: pointer;
    padding: 0;
    position: relative;
}
.kk-nav-toggle span,
.kk-nav-toggle span::before,
.kk-nav-toggle span::after {
    content: '';
    position: absolute;
    left: 12px;
    width: 20px; height: 2px;
    background: #fff;
    border-radius: 2px;
    transition: transform .22s ease, opacity .18s ease;
}
.kk-nav-toggle span { top: 21px; }
.kk-nav-toggle span::before { left: 0; top: -6px; }
.kk-nav-toggle span::after  { left: 0; top: 6px; }
.kk-nav-toggle[aria-expanded="true"] span { background: transparent; }
.kk-nav-toggle[aria-expanded="true"] span::before { transform: translateY(6px) rotate(45deg); }
.kk-nav-toggle[aria-expanded="true"] span::after  { transform: translateY(-6px) rotate(-45deg); }

@media (max-width: 900px) {
    .kk-nav-toggle { display: block; }
    .kk-header__nav {
        position: fixed;
        inset: 74px 0 auto;
        background: var(--kk-night);
        border-top: 1px solid var(--kk-divider-dark);
        padding: 14px var(--kk-gutter) 26px;
        display: none;
        max-height: calc(100dvh - 74px);
        overflow-y: auto;
    }
    .kk-header__nav.is-open { display: block; }
    .kk-menu { flex-direction: column; align-items: stretch; gap: 2px; }
    .kk-menu a { padding: 13px 14px; font-size: var(--kk-t-md); }
    .kk-menu .sub-menu { display: block; position: static; background: transparent; box-shadow: none; padding-left: 12px; }
    .kk-header__cta { display: none; }
    .kk-header__nav .kk-header__cta { display: inline-flex; margin-top: 14px; width: 100%; }
}

/* ==========================================================================
   HERO - the night
   ========================================================================== */
.kk-hero {
    position: relative;
    /* The header floats over this, so the top padding has to clear it. */
    padding: clamp(96px, 13vw, 150px) 0 clamp(90px, 11vw, 140px);
    background:
        radial-gradient(120% 90% at 78% 8%,  rgba(246, 185, 59, .17) 0%, transparent 58%),
        radial-gradient(90% 70% at 12% 92%,  rgba(163, 144, 212, .18) 0%, transparent 62%),
        linear-gradient(178deg, #0B0A1A 0%, var(--kk-night) 46%, #1B1738 100%);
    color: var(--kk-text-light);
    overflow: hidden;
    isolation: isolate;
}
.kk-hero h1 { color: #fff; }
.kk-hero h1 em {
    display: block;
    font-style: normal;
    color: var(--kk-gold);
}
.kk-hero .kk-lede { color: #C7C0DC; max-width: 46ch; }

.kk-hero__grid {
    display: grid;
    grid-template-columns: minmax(0, 1.02fr) minmax(0, .98fr);
    gap: clamp(34px, 6vw, 68px);
    align-items: center;
}
.kk-hero__ctas { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 26px; }
.kk-hero__note {
    margin-top: 18px;
    font-size: var(--kk-t-sm);
    color: var(--kk-text-dim);
}

/* The moon. One shape, and it does a lot of work: it is the only thing on
   the page that says "night" without any words. */
.kk-moon {
    position: absolute;
    top: clamp(40px, 9vw, 96px);
    right: clamp(-40px, 4vw, 70px);
    width: clamp(140px, 22vw, 260px);
    aspect-ratio: 1;
    border-radius: 50%;
    background: radial-gradient(circle at 36% 32%, #FFE9B8 0%, var(--kk-gold) 58%, #D89626 100%);
    box-shadow: 0 0 130px 26px rgba(246, 185, 59, .22);
    opacity: .5;
    z-index: -1;
    pointer-events: none;
}

/* --- the star field ------------------------------------------------------
   Positions are computed in PHP from a fixed seed, so the sky is identical
   on every load. A star field that reshuffles on refresh reads as a bug. */
.kk-stars { position: absolute; inset: 0; pointer-events: none; z-index: 0; }
.kk-star {
    position: absolute;
    border-radius: 50%;
    background: #fff;
    opacity: .5;
    animation: kk-twinkle 4.2s ease-in-out infinite;
}
.kk-star:nth-child(4n)   { background: var(--kk-gold); }
.kk-star:nth-child(7n)   { background: var(--kk-lavender); }
@keyframes kk-twinkle {
    0%, 100% { opacity: .16; transform: scale(.7); }
    50%      { opacity: .9;  transform: scale(1); }
}

/* --- the phone that holds the app's intro video -------------------------- */
.kk-showreel {
    position: relative;
    justify-self: center;
    width: min(310px, 78vw);
}
.kk-phone {
    position: relative;
    border-radius: 42px;
    padding: 11px;
    background: linear-gradient(160deg, #38325C 0%, #191634 46%, #2B2650 100%);
    box-shadow:
        0 40px 90px -30px rgba(0, 0, 0, .75),
        0 0 0 1px rgba(255, 255, 255, .09) inset,
        var(--kk-glow);
}
.kk-phone::after {
    /* the speaker notch */
    content: '';
    position: absolute;
    top: 20px; left: 50%;
    transform: translateX(-50%);
    width: 82px; height: 6px;
    border-radius: 99px;
    background: rgba(0, 0, 0, .55);
    z-index: 3;
}
.kk-phone__screen {
    position: relative;
    border-radius: 32px;
    overflow: hidden;
    aspect-ratio: 9 / 19.5;
    background: #0B0A1A;
}
.kk-phone__screen > video,
.kk-phone__screen > img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Sound control. The video autoplays muted because every browser demands
   it; this is how a visitor turns the story on. It is deliberately large
   and deliberately labelled - a bare speaker glyph is missed. */
.kk-sound {
    position: absolute;
    left: 50%;
    bottom: 16px;
    transform: translateX(-50%);
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 10px 16px;
    border: 0;
    border-radius: 999px;
    background: rgba(11, 10, 26, .74);
    backdrop-filter: blur(8px);
    color: #fff;
    font-family: var(--kk-body);
    font-size: var(--kk-t-xs);
    font-weight: 700;
    letter-spacing: .04em;
    cursor: pointer;
    z-index: 4;
    transition: background-color .18s ease;
}
.kk-sound:hover { background: rgba(238, 108, 77, .92); }
.kk-sound__icon { width: 15px; height: 15px; flex: none; }

/* The glow behind the phone - the "lamp in a dark room" the whole hero is
   built around. Pure decoration, and it is the single detail that makes the
   section feel lit rather than merely dark. */
.kk-showreel::before {
    content: '';
    position: absolute;
    inset: -14% -22%;
    background: radial-gradient(closest-side, rgba(246, 185, 59, .3), transparent 72%);
    filter: blur(30px);
    z-index: -1;
    animation: kk-breathe 7s ease-in-out infinite;
}
@keyframes kk-breathe {
    0%, 100% { opacity: .55; transform: scale(1); }
    50%      { opacity: .95; transform: scale(1.07); }
}

/* --- the drawn scene, used when no intro video is set ------------------- */
.kk-scene svg { width: 100%; height: auto; border-radius: var(--kk-radius-lg); }
.kk-scene--photo img { border-radius: var(--kk-radius-lg); box-shadow: var(--kk-shadow-lg); }

/* --- trust strip under the hero copy ------------------------------------ */
.kk-trust {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 22px;
    margin-top: 30px;
    padding: 0;
    list-style: none;
}
.kk-trust li {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: var(--kk-t-sm);
    font-weight: 600;
    color: #BDB5D4;
}
.kk-trust svg { width: 17px; height: 17px; flex: none; color: var(--kk-teal); }

/* ==========================================================================
   Wave dividers - the seams between night and day
   ========================================================================== */
.kk-wave { position: absolute; left: 0; right: 0; line-height: 0; pointer-events: none; }
.kk-wave svg { width: 100%; height: clamp(38px, 6vw, 84px); display: block; }
.kk-wave--to-cream { bottom: -1px; color: var(--kk-cream); }
.kk-wave--to-muted { bottom: -1px; color: var(--kk-muted); }
.kk-wave--to-night  { color: var(--kk-night); }
.kk-wave--top { top: -1px; bottom: auto; }

/* ==========================================================================
   The category ribbon - live from the app, in both scripts
   ========================================================================== */
.kk-ribbon-band {
    background: var(--kk-cream);
    padding-block: clamp(16px, 2.5vw, 26px);
    overflow: hidden;
}

/* ==========================================================================
   Cards, grids, features - the daylight half
   ========================================================================== */
.kk-features {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: clamp(16px, 2.4vw, 26px);
}
.kk-feature {
    background: var(--kk-surface);
    border: 1px solid var(--kk-divider);
    border-radius: var(--kk-radius);
    padding: 30px 26px;
    transition: transform .22s ease, box-shadow .22s ease;
}
.kk-feature:hover { transform: translateY(-5px); box-shadow: var(--kk-shadow); }
.kk-feature h3 { font-size: var(--kk-t-lg); margin-bottom: .4em; }
.kk-feature p { color: var(--kk-text-muted); font-size: var(--kk-t-sm); margin: 0; }
.kk-feature__icon { display: block; width: 52px; height: 52px; margin-bottom: 18px; }
.kk-feature--coral    { color: var(--kk-primary); }
.kk-feature--teal     { color: var(--kk-teal); }
.kk-feature--gold     { color: #D9942A; }
.kk-feature--lavender { color: #7E68B5; }
.kk-feature h3, .kk-feature p { color: var(--kk-text); }
.kk-feature p { color: var(--kk-text-muted); }

/* --- how it works ------------------------------------------------------- */
.kk-steps {
    list-style: none;
    counter-reset: kk;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: clamp(18px, 3vw, 34px);
}
.kk-step { display: flex; gap: 16px; align-items: flex-start; }
.kk-step__num {
    flex: none;
    display: grid;
    place-items: center;
    width: 46px; height: 46px;
    border-radius: 50%;
    background: var(--kk-primary);
    color: #fff;
    font-family: var(--kk-display);
    font-weight: 700;
    font-size: 1.24rem;
    box-shadow: 0 10px 22px -10px rgba(238, 108, 77, .8);
}
.kk-step h3 { font-size: var(--kk-t-lg); margin-bottom: .3em; }
.kk-step p { color: var(--kk-text-muted); font-size: var(--kk-t-sm); margin: 0; }

/* ==========================================================================
   INSIDE THE APP - the promotion band
   ========================================================================== */
.kk-inside {
    position: relative;
    background:
        radial-gradient(80% 60% at 50% 0%, rgba(163, 144, 212, .2) 0%, transparent 60%),
        linear-gradient(180deg, #1B1738 0%, var(--kk-night) 55%, #0F0D24 100%);
    color: var(--kk-text-light);
    overflow: hidden;
    padding-block: clamp(80px, 10vw, 130px);
}
.kk-inside h2 { color: #fff; }

.kk-inside__stage {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: clamp(-40px, -2vw, 0px);
    min-height: 520px;
    margin-bottom: 34px;
}

/* Three phones. The middle one is live; the outer two are dimmed, rotated
   and pushed back, so the eye is told where to look without a caption
   saying so. On a narrow screen the outer two are removed rather than
   shrunk - three tiny phones on a 390px screen is three unreadable
   phones. */
.kk-inside__phone {
    position: relative;
    width: min(270px, 68vw);
    transition: transform .7s cubic-bezier(.22, .8, .28, 1), opacity .7s ease, filter .7s ease;
}
.kk-inside__phone--side {
    width: min(220px, 52vw);
    opacity: .58;
    filter: saturate(.7) blur(.4px);
    z-index: 1;
}
.kk-inside__phone--left  { transform: translateX(38%) rotate(-7deg) scale(.9); }
.kk-inside__phone--right { transform: translateX(-38%) rotate(7deg) scale(.9); }
.kk-inside__phone--main  { z-index: 2; }

/* The rotating shelf inside the middle phone. Real cover art from the API,
   so this can never be a screenshot of a version that no longer exists. */
.kk-shelf {
    position: absolute;
    inset: 0;
    display: grid;
    grid-template-columns: 1fr 1fr;
    /* Rows size themselves from each tile's aspect-ratio. An earlier
       `grid-auto-rows: min-content` collapsed the row to the image's minimum
       height and aspect-ratio then derived the width from THAT, which turned
       every cover into a 40px dot. */
    align-content: start;
    gap: 10px;
    padding: 50px 13px 13px;
    background: linear-gradient(180deg, #1B1738 0%, #14122B 100%);
    overflow: hidden;
}
.kk-shelf__head {
    grid-column: 1 / -1;
    font-family: var(--kk-display);
    font-size: .96rem;
    font-weight: 700;
    color: #fff;
    margin: 0 0 2px;
}
.kk-shelf__tile {
    position: relative;
    border-radius: 12px;
    overflow: hidden;
    aspect-ratio: 1;
    background: #262147;
    animation: kk-tile-in .6s both;
}
.kk-shelf__tile img { width: 100%; height: 100%; object-fit: cover; }
.kk-shelf__tile figcaption {
    position: absolute;
    inset: auto 0 0;
    padding: 14px 8px 6px;
    background: linear-gradient(transparent, rgba(11, 10, 26, .9));
    font-size: .6rem;
    font-weight: 600;
    color: #fff;
    line-height: 1.25;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}
@keyframes kk-tile-in {
    from { opacity: 0; transform: translateY(10px) scale(.96); }
    to   { opacity: 1; transform: none; }
}

/* The three captions under the stage, one per screen, advanced by the same
   control that advances the phones. */
.kk-inside__caption {
    text-align: center;
    min-height: 92px;
}
.kk-inside__caption h3 { color: #fff; font-size: var(--kk-t-xl); margin-bottom: .3em; }
.kk-inside__caption p { color: var(--kk-text-dim); margin-inline: auto; max-width: 46ch; }

.kk-dots { display: flex; gap: 9px; justify-content: center; margin-top: 22px; }
.kk-dot {
    width: 9px; height: 9px;
    border: 0;
    border-radius: 50%;
    padding: 0;
    background: rgba(255, 255, 255, .28);
    cursor: pointer;
    transition: background-color .25s ease, width .25s ease;
}
.kk-dot.is-active { background: var(--kk-gold); width: 26px; border-radius: 99px; }

.kk-inside__nav {
    position: absolute;
    top: 46%;
    width: 46px; height: 46px;
    display: grid;
    place-items: center;
    border: 1px solid rgba(255, 255, 255, .2);
    border-radius: 50%;
    background: rgba(255, 255, 255, .07);
    color: #fff;
    cursor: pointer;
    backdrop-filter: blur(8px);
    z-index: 5;
    transition: background-color .2s ease, transform .2s ease;
}
.kk-inside__nav:hover { background: rgba(238, 108, 77, .9); transform: scale(1.07); }
.kk-inside__nav--prev { left: 0; }
.kk-inside__nav--next { right: 0; }
.kk-inside__nav svg { width: 18px; height: 18px; }

@media (max-width: 820px) {
    .kk-inside__phone--side { display: none; }
    .kk-inside__stage { min-height: 470px; }
    .kk-inside__nav { top: auto; bottom: -8px; }
}

/* ==========================================================================
   Download band
   ========================================================================== */
/* Nothing here.
   THIS is what was breaking the badges (found 2026-09-10 from Unni's
   screenshots). It used to read:

       .kk-store-badges img { height: 52px; width: auto; }
       .kk-store-badges a   { display: inline-block; ... }

   written for image badges that this site does not use - the plugin builds
   them from a logo and two lines of text. `.kk-store-badges a` is one class
   plus one type, which OUTRANKS the component layer's `.kk-store-badge`, so
   `inline-block` beat `inline-flex` no matter which came later in the file.
   With the flex gone the logo stacked on top of the words and the two badges
   ended up different heights.

   The lesson is the specificity, not the property: a descendant selector
   written against markup you are guessing at will quietly outrank the real
   component rule. */

/* ==========================================================================
   Footer
   ========================================================================== */
.kk-footer {
    background: var(--kk-night-2);
    color: var(--kk-text-dim);
    padding-block: clamp(48px, 6vw, 76px) 26px;
    font-size: var(--kk-t-sm);
}
.kk-footer__grid {
    display: grid;
    /* Four columns, the brand a little wider than the rest. The old
       `repeat(auto-fit, minmax(160px, 1fr))` produced three columns across
       1180px, which left the last one ending well short of the right edge -
       the "too wide, unwanted gaps" Unni marked up. */
    grid-template-columns: minmax(0, 1.5fr) repeat(3, minmax(0, 1fr));
    gap: clamp(24px, 3vw, 44px);
    align-items: start;
}
.kk-footer__brand p { font-size: var(--kk-t-sm); }

/* The menu in two sub-columns. Six links in a single file is six rows of
   mostly empty space; in two it is three, and the block then sits at the
   same height as the ones beside it instead of dragging the footer down. */
.kk-footer__menu ul,
.kk-footer__menu .kk-menu {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px 16px;
    list-style: none;
    margin: 0;
    padding: 0;
}
/* wp_nav_menu prints .kk-menu, which the HEADER styles as a horizontal bar.
   Inside the footer it has to be a plain grid again. */
.kk-footer__menu .kk-menu a {
    display: block;
    padding: 0;
    border-radius: 0;
    background: none;
    font-size: var(--kk-t-sm);
    font-weight: 400;
    color: var(--kk-text-dim);
}
.kk-footer__menu .kk-menu a:hover,
.kk-footer__menu .kk-menu .current-menu-item > a { background: none; color: var(--kk-gold); }
.kk-footer h4 {
    color: #fff;
    font-size: var(--kk-t-md);
    margin-bottom: 14px;
}
.kk-footer img { max-height: 46px; width: auto; margin-bottom: 16px; }
.kk-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.kk-footer a { color: var(--kk-text-dim); text-decoration: none; }
.kk-footer a:hover { color: var(--kk-gold); }
.kk-footer__bottom {
    margin-top: clamp(30px, 4vw, 48px);
    padding-top: 20px;
    border-top: 1px solid var(--kk-divider-dark);
    display: flex;
    flex-wrap: wrap;
    gap: 6px 20px;
    /* Centred as a pair rather than thrown to opposite edges of 1180px.
       Two short lines a metre apart do not read as one row. */
    justify-content: center;
    text-align: center;
    font-size: var(--kk-t-xs);
    color: var(--kk-text-dim);
}
.kk-footer__bottom span + span::before {
    content: '·';
    margin-right: 20px;
    opacity: .5;
}

@media (max-width: 900px) {
    .kk-footer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .kk-footer__brand { grid-column: 1 / -1; }
}
@media (max-width: 520px) {
    .kk-footer__bottom span + span::before { content: none; margin: 0; }
}

/* ==========================================================================
   Ordinary WordPress pages
   ========================================================================== */
.kk-page { padding-block: clamp(52px, 7vw, 92px); }
.kk-page__head { text-align: center; margin-bottom: clamp(30px, 4vw, 50px); }
.kk-prose { max-width: 720px; margin-inline: auto; }
.kk-prose h2 { margin-top: 1.6em; }
.kk-prose h3 { margin-top: 1.4em; font-size: var(--kk-t-lg); }
.kk-prose ul, .kk-prose ol { padding-left: 1.25em; }
.kk-prose li { margin-bottom: .5em; }
.kk-prose img { border-radius: var(--kk-radius-sm); }
.kk-prose blockquote {
    margin: 1.6em 0;
    padding: 4px 0 4px 22px;
    border-left: 4px solid var(--kk-gold);
    font-family: var(--kk-display);
    font-size: var(--kk-t-lg);
    color: var(--kk-text);
}
.kk-prose table { width: 100%; border-collapse: collapse; }
.kk-prose > .kk-table-scroll,
.kk-table-scroll { overflow-x: auto; }

/* ==========================================================================
   Reveal on scroll
   ========================================================================== */
.kk-reveal {
    opacity: 0;
    transform: translateY(18px);
    transition: opacity .65s ease, transform .65s cubic-bezier(.22, .8, .28, 1);
}
.kk-reveal.is-in { opacity: 1; transform: none; }

/* ==========================================================================
   Ambient motion for the drawn scene
   ========================================================================== */
@keyframes kk-float      { 0%,100% { transform: translateY(0); }  50% { transform: translateY(-9px); } }
@keyframes kk-float-slow { 0%,100% { transform: translateY(0); }  50% { transform: translateY(-6px); } }
@keyframes kk-sway       { 0%,100% { transform: rotate(-1.4deg); } 50% { transform: rotate(1.4deg); } }
@keyframes kk-firefly    { 0%,100% { opacity: .15; } 45% { opacity: 1; } }

.kk-float      { animation: kk-float 5s ease-in-out infinite; }
.kk-float-slow { animation: kk-float-slow 7s ease-in-out infinite; }
.kk-sway       { animation: kk-sway 6s ease-in-out infinite; transform-origin: 77px 250px; }
.kk-bob        { animation: kk-float-slow 6s ease-in-out infinite; }
.kk-bob--1     { animation-delay: .4s; }
.kk-bob--2     { animation-delay: 1.1s; }
.kk-bob--3     { animation-delay: 1.9s; }
.kk-firefly    { animation: kk-firefly 3.4s ease-in-out infinite; }
.kk-firefly--2 { animation-delay: .7s; }
.kk-firefly--3 { animation-delay: 1.4s; }
.kk-firefly--4 { animation-delay: 2.1s; }
.kk-firefly--5 { animation-delay: 2.8s; }

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width: 980px) {
    .kk-hero__grid {
        grid-template-columns: 1fr;
        text-align: center;
    }
    .kk-hero .kk-lede { margin-inline: auto; }
    .kk-hero__ctas { justify-content: center; }
    .kk-trust { justify-content: center; }
    .kk-showreel { margin-top: 12px; width: min(250px, 62vw); }
    .kk-moon { top: 8px; right: -50px; opacity: .35; }
}

@media (max-width: 640px) {
    :root { --kk-radius: 18px; --kk-radius-lg: 26px; }
    .kk-hero { padding-top: clamp(84px, 22vw, 110px); }
    .kk-btn { padding: 14px 22px; }
    .kk-btn--lg { padding: 16px 26px; font-size: var(--kk-t-md); }
    .kk-hero__ctas .kk-btn { flex: 1 1 100%; }
    .kk-steps { gap: 22px; }
    .kk-footer__grid { grid-template-columns: 1fr; }
    .kk-footer__bottom { justify-content: center; text-align: center; }
    /* (the img rule that used to sit here went with the block above) */
}

/* Every animation on this site is atmosphere, never information. Turning
   them all off costs the visitor nothing but the mood. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
    }
    .kk-reveal { opacity: 1; transform: none; }
}

/* Printing a policy page should give a readable document, not a night sky. */
@media print {
    .kk-header, .kk-footer, .kk-hero, .kk-inside, .kk-wave, .kk-stars, .kk-moon { display: none !important; }
    body { background: #fff; color: #000; }
}

/* ==========================================================================
   The drawn phone screens in "Inside the app"

   Rendered in HTML and CSS rather than shipped as images: sharp at any
   density, weightless, and they re-colour themselves if the palette changes
   in the Customizer.
   ========================================================================== */
.kk-screen {
    position: absolute;
    inset: 0;
    opacity: 0;
    visibility: hidden;
    transition: opacity .45s ease;
}
.kk-screen.is-active { opacity: 1; visibility: visible; }

/* The captions under the stage are the same mechanism, but they must take
   part in flow so the block keeps its height as the text changes. */
.kk-inside__caption .kk-screen { position: static; }
.kk-inside__caption .kk-screen:not(.is-active) { display: none; }

.kk-shelf__tile--empty { opacity: .55; }

.kk-mock {
    position: absolute;
    inset: 0;
    padding: 52px 18px 20px;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    background: linear-gradient(180deg, #1B1738 0%, #14122B 100%);
    color: #fff;
    font-family: var(--kk-body);
}
.kk-mock p { margin: 0; max-width: none; }

/* --- player -------------------------------------------------------------- */
.kk-mock__art {
    width: 76%;
    aspect-ratio: 1;
    border-radius: 18px;
    overflow: hidden;
    background: linear-gradient(140deg, var(--kk-lavender), var(--kk-primary));
    box-shadow: 0 18px 40px -16px rgba(0, 0, 0, .8);
    margin-bottom: 18px;
    flex: none;
}
.kk-mock__art img { width: 100%; height: 100%; object-fit: cover; }
.kk-mock__artfall {
    display: block; width: 100%; height: 100%;
    background: radial-gradient(circle at 34% 30%, rgba(255,255,255,.35), transparent 60%);
}
.kk-mock__title {
    font-family: var(--kk-display);
    font-size: .92rem;
    font-weight: 700;
    line-height: 1.25;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.kk-mock__sub {
    font-size: .64rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--kk-gold);
    margin-top: 4px !important;
}

.kk-mock__wave {
    display: flex;
    align-items: center;
    gap: 2px;
    height: 34px;
    width: 88%;
    margin: 16px 0 14px;
}
.kk-mock__wave i {
    flex: 1;
    min-width: 0;
    border-radius: 2px;
    background: rgba(255, 255, 255, .22);
}
.kk-mock__wave i.is-played { background: var(--kk-gold); }

.kk-mock__transport {
    display: flex;
    align-items: center;
    gap: 18px;
}
.kk-mock__btn {
    display: grid;
    place-items: center;
    width: 34px; height: 34px;
    border-radius: 50%;
    border: 1.5px solid rgba(255, 255, 255, .3);
    font-size: .58rem;
    font-weight: 700;
    color: rgba(255, 255, 255, .75);
}
.kk-mock__btn--play {
    width: 56px; height: 56px;
    border: 0;
    background: var(--kk-primary);
    box-shadow: 0 12px 26px -10px rgba(238, 108, 77, .9);
    position: relative;
}
.kk-mock__btn--play::after {
    content: '';
    width: 0; height: 0;
    margin-left: 4px;
    border-left: 15px solid #fff;
    border-top: 10px solid transparent;
    border-bottom: 10px solid transparent;
}

/* --- bedtime ------------------------------------------------------------- */
.kk-mock--night { justify-content: center; gap: 14px; }
.kk-mock__moon {
    width: 74px; height: 74px;
    border-radius: 50%;
    background: radial-gradient(circle at 36% 32%, #FFE9B8, var(--kk-gold) 60%, #D89626);
    box-shadow: 0 0 54px 10px rgba(246, 185, 59, .35);
    animation: kk-breathe 6s ease-in-out infinite;
}
.kk-mock__eyebrow {
    font-size: .6rem;
    font-weight: 700;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--kk-text-dim);
}
.kk-mock__clock {
    font-family: var(--kk-display);
    font-size: 2.5rem;
    font-weight: 700;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}
.kk-mock__clock small { font-size: .46em; color: var(--kk-text-dim); }
.kk-mock__chips { display: flex; gap: 6px; }
.kk-mock__chips span {
    padding: 5px 11px;
    border-radius: 999px;
    border: 1px solid rgba(255, 255, 255, .18);
    font-size: .62rem;
    font-weight: 600;
    color: rgba(255, 255, 255, .6);
}
.kk-mock__chips .is-on {
    background: var(--kk-gold);
    border-color: var(--kk-gold);
    color: var(--kk-night);
}
.kk-mock__namecard {
    margin-top: 6px;
    padding: 13px 14px;
    border-radius: 16px;
    background: rgba(255, 255, 255, .07);
    border: 1px solid rgba(255, 255, 255, .12);
}
.kk-mock__mal {
    font-family: var(--kk-mal);
    font-size: .95rem;
    font-weight: 600;
    line-height: 1.5;
    color: #fff;
}
.kk-mock__en {
    margin-top: 5px !important;
    font-size: .6rem;
    line-height: 1.45;
    color: var(--kk-text-dim);
}


/* ==========================================================================
   COMPONENT LAYER - carried forward from v2 unchanged.

   Everything below styles markup produced by the Katha Kutty Connect PLUGIN
   (story cards, pricing, the offers carousel, featured banners, the sample
   player, the end-of-sample card, the contact form, the WhatsApp bubble and
   the category ribbon) plus the founding banner and store badges.

   None of it is re-typed for the redesign, deliberately. Every rule here
   already takes its colours from the --kk-* tokens redefined at the top of
   this file, so the new palette reaches all of it for free - and re-writing
   working CSS for a hundred selectors would only be an opportunity to break
   something nobody would notice until a parent hit it.

   The few places where the new design needs these to look different are
   overridden at the very bottom of this file, after everything, rather than
   edited in place - so the seam between "carried forward" and "changed for
   v3" stays visible.
   ========================================================================== */
/* ==========================================================================
   Story cards (markup from the Connect plugin)
   ========================================================================== */
.kk-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(215px, 1fr)); gap: 24px; }

.kk-card {
    background: var(--kk-surface); border-radius: var(--kk-radius-lg);
    overflow: hidden; box-shadow: var(--kk-shadow);
    transition: transform .25s ease, box-shadow .25s ease;
    display: flex; flex-direction: column;
}
.kk-card:hover { transform: translateY(-8px) rotate(.6deg); box-shadow: var(--kk-shadow-lift); }
.kk-card:nth-child(even):hover { transform: translateY(-8px) rotate(-.6deg); }

.kk-card__art { position: relative; aspect-ratio: 1 / 1; display: grid; place-items: center; overflow: hidden; }
.kk-card__img { width: 100%; height: 100%; object-fit: cover; }
.kk-card__fallback { font-size: 3rem; opacity: .78; }
.kk-card--coral    .kk-card__art { background: linear-gradient(150deg, #FBD9D2, #F4A896); }
.kk-card--gold     .kk-card__art { background: linear-gradient(150deg, #FCEBC7, #F2B441); }
.kk-card--teal     .kk-card__art { background: linear-gradient(150deg, #CDE7E2, #7FBFB4); }
.kk-card--lavender .kk-card__art { background: linear-gradient(150deg, #E2DAEC, #B7A6CE); }

.kk-card__tag {
    position: absolute; top: 12px; right: 12px;
    font-family: var(--kk-display); font-weight: 700; font-size: .7rem;
    letter-spacing: .04em; text-transform: uppercase;
    padding: 5px 11px; border-radius: var(--kk-radius-pill);
    background: rgba(255, 248, 240, .94); color: var(--kk-night);
    box-shadow: 0 2px 8px rgba(43, 21, 18, .18);
}
/* Bottom-left, not top-left. Both badges shared the top edge, and on a
   narrow card - three across an iPad, two across a phone - "Apple's Choice"
   ran straight under the Premium pill. Opposite corners cannot collide
   however narrow the card gets. */
.kk-card__ribbon {
    position: absolute; bottom: 12px; left: 12px; max-width: calc(100% - 24px);
    font-family: var(--kk-display); font-weight: 700; font-size: .68rem;
    padding: 5px 10px; border-radius: var(--kk-radius-pill);
    background: var(--kk-night); color: var(--kk-gold);
    box-shadow: 0 2px 8px rgba(43, 21, 18, .28);
}
.kk-card__body { padding: 17px 18px 20px; display: flex; flex-direction: column; gap: 6px; flex: 1; }
.kk-card__title { font-size: 1.05rem; font-weight: 700; line-height: 1.28; }
.kk-card__meta { margin: 0; color: var(--kk-text-muted); font-size: .86rem; }
.kk-card__type { margin-top: auto; padding-top: 8px; font-size: .84rem; font-weight: 600; color: var(--kk-primary-dark); }

.kk-empty {
    text-align: center; padding: 56px 24px;
    background: var(--kk-surface); border-radius: var(--kk-radius-lg);
    box-shadow: var(--kk-shadow); color: var(--kk-text-muted);
}
.kk-empty__icon { font-size: 2.6rem; display: block; margin-bottom: 12px; }


/* ==========================================================================
   Pricing
   ========================================================================== */
.kk-pricing-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(255px, 1fr)); gap: 26px; align-items: start; }
.kk-price-card {
    position: relative; background: var(--kk-surface);
    border-radius: var(--kk-radius-lg); padding: 34px 28px 30px;
    box-shadow: var(--kk-shadow); border: 3px solid transparent;
    transition: transform .25s ease, box-shadow .25s ease;
    text-align: center;
}
.kk-price-card:hover { transform: translateY(-6px); box-shadow: var(--kk-shadow-lift); }
.kk-price-card--popular { border-color: var(--kk-primary); }
.kk-price-card__ribbon {
    position: absolute; top: -15px; left: 50%; transform: translateX(-50%);
    background: var(--kk-primary); color: #fff; white-space: nowrap;
    font-family: var(--kk-display); font-weight: 700; font-size: .74rem;
    padding: 6px 18px; border-radius: var(--kk-radius-pill);
    box-shadow: 0 5px 14px rgba(232, 93, 78, .38);
}
.kk-price-card__label { font-family: var(--kk-display); font-weight: 700; font-size: 1.16rem; }
.kk-price-card__amount {
    font-family: var(--kk-display); font-weight: 800;
    font-size: 2.5rem; color: var(--kk-primary-dark); margin: 6px 0 2px;
    font-variant-numeric: tabular-nums;
}
.kk-price-card__amount span { font-size: .88rem; font-weight: 600; color: var(--kk-text-muted); }
.kk-price-card__strike { color: var(--kk-text-muted); font-size: .9rem; }
.kk-price-card__strike s { text-decoration: line-through; text-decoration-thickness: 2px; }
.kk-price-card__devices { color: var(--kk-text-muted); font-size: .92rem; margin: 12px 0 20px; }


/* ==========================================================================
   Founding banner
   ========================================================================== */
.kk-founding-banner {
    display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 6px 14px;
    background: linear-gradient(100deg, var(--kk-night), var(--kk-night-2));
    color: var(--kk-text-light); text-align: center;
    border-radius: var(--kk-radius); padding: 17px 26px;
    /* WAS margin: -18px auto 0 - a negative top margin that lifted the
       banner over whatever sat above it. Under the old layout that was a
       section with generous padding and the overlap was intentional; here it
       lands on the category ribbon and slices the chips in half.
       Narrower, too: full container width made an announcement bar out of
       what should read as a badge. */
    max-width: 760px;
    margin: 26px auto 4px; position: relative; z-index: 3;
    box-shadow: var(--kk-shadow-lift);
    font-size: .98rem;
}
.kk-founding-banner strong { color: var(--kk-gold); font-family: var(--kk-display); }
.kk-founding-banner__spark { animation: kk-twinkle 2.6s ease-in-out infinite; }


/* ==========================================================================
   Store badges
   ========================================================================== */
/* Two platforms, one weight. iOS is not shipped yet, but an iPhone visitor
   has to be able to see that this app is for their phone too - so the Apple
   badge is the same size and sits in the same row, and the day an App Store
   URL is entered it simply becomes a working link. */
.kk-store-badges { display: flex; gap: 13px; flex-wrap: wrap; margin-top: 26px; }
.kk-store-badge {
    position: relative;
    display: inline-flex; align-items: center; gap: 11px;
    min-width: 190px;
    background: var(--kk-surface); color: var(--kk-night);
    padding: 11px 22px; border-radius: var(--kk-radius-pill);
    text-decoration: none; box-shadow: var(--kk-shadow);
    transition: transform .2s ease, box-shadow .2s ease;
}
.kk-store-badge:hover { transform: translateY(-3px); box-shadow: var(--kk-shadow-lift); }
.kk-store-badge__logo { width: 26px; height: 26px; flex: none; }
.kk-store-badge__text { display: block; line-height: 1.15; }
.kk-store-badge__text small {
    display: block; font-size: .68rem; font-weight: 600;
    letter-spacing: .06em; text-transform: uppercase; color: var(--kk-text-muted);
}
.kk-store-badge__text strong { display: block; font-family: var(--kk-display); font-size: 1.08rem; color: var(--kk-night); }
/* The footer's link colour is light-on-dark and beat the badge's own
   colour on specificity, which turned "Google Play" white on a white
   pill - invisible. Stated explicitly here so no surrounding context can
   take it over again. */
.kk-footer .kk-store-badge, .kk-footer .kk-store-badge__text strong { color: var(--kk-night); }

/* Waiting for iOS - present and clickable, never a dead grey pill. */
.kk-store-badge--soon { background: rgba(255, 248, 240, .92); align-items: center; }
.kk-store-badge--soon .kk-store-badge__logo { opacity: .75; }
/* In the text stack, not floating over it: absolutely positioned, the pill
   sat on top of the words "App Store" as soon as a badge went full-width
   on a phone. */
.kk-store-badge__nudge {
    display: inline-block; margin-top: 5px; white-space: nowrap;
    font-family: var(--kk-body); font-size: .68rem; font-weight: 700;
    color: var(--kk-night); background: var(--kk-gold);
    padding: 2px 10px; border-radius: var(--kk-radius-pill);
}
.kk-store-badges { align-items: center; }

/* The phone in the visitor's hand goes first. */
.kk-is-ios .kk-store-badge--ios { order: -1; }


/* ==========================================================================
   Sample clip player (markup from the Connect plugin)

   The button sits on the card artwork and fills with a progress sweep as
   the clip plays. Deliberately understated: this is a taste of a story,
   not a media player, so there is no scrubber, no timecode and no volume -
   just play, listen, stop.
   ========================================================================== */
.kk-play {
    position: absolute; left: 50%; top: 50%;
    transform: translate(-50%, -50%) scale(.92);
    width: 58px; height: 58px; padding: 0;
    border: 0; border-radius: 50%; cursor: pointer;
    background: rgba(255, 248, 240, .93);
    box-shadow: 0 8px 22px rgba(43, 21, 18, .3);
    display: grid; place-items: center;
    opacity: 0; transition: opacity .22s ease, transform .22s ease, background .2s ease;
    --kk-progress: 0%;
}
/* Always visible on touch devices, where there is no hover to reveal it. */
.kk-card:hover .kk-play,
.kk-play:focus-visible,
.kk-play.is-playing,
.kk-play.is-loading { opacity: 1; transform: translate(-50%, -50%) scale(1); }
@media (hover: none) { .kk-play { opacity: 1; transform: translate(-50%, -50%) scale(1); } }

.kk-play:hover { background: #fff; }

/* Play triangle, drawn with borders so it needs no extra markup. */
.kk-play__icon {
    width: 0; height: 0; margin-left: 4px;
    border-style: solid; border-width: 10px 0 10px 17px;
    border-color: transparent transparent transparent var(--kk-primary);
    transition: border-width .18s ease, margin .18s ease;
}
/* Becomes a pause bar pair while playing. */
.kk-play.is-playing .kk-play__icon {
    margin-left: 0;
    width: 16px; height: 18px;
    border: 0;
    background: linear-gradient(to right,
        var(--kk-primary) 0 5px, transparent 5px 11px, var(--kk-primary) 11px 16px);
}
.kk-play.is-loading .kk-play__icon {
    margin-left: 0; width: 18px; height: 18px; border: 0;
    border-radius: 50%;
    background: conic-gradient(var(--kk-primary) 0 90deg, transparent 90deg 360deg);
    -webkit-mask: radial-gradient(circle, transparent 5px, #000 6px);
    mask: radial-gradient(circle, transparent 5px, #000 6px);
    animation: kk-spin .8s linear infinite;
}
@keyframes kk-spin { to { transform: rotate(360deg); } }

/* Progress sweep around the button. */
.kk-play__ring {
    position: absolute; inset: -4px; border-radius: 50%;
    background: conic-gradient(var(--kk-gold) var(--kk-progress), transparent 0);
    -webkit-mask: radial-gradient(circle, transparent 30px, #000 31px);
    mask: radial-gradient(circle, transparent 30px, #000 31px);
    opacity: 0; transition: opacity .2s ease;
}
.kk-play.is-playing .kk-play__ring { opacity: 1; }

.kk-card__art { position: relative; }


/* ==========================================================================
   End-of-sample card (markup from the Connect plugin)

   Opens only when a sample clip finishes on its own - the one moment the
   visitor is already asking "and then what?". Built to feel like the story
   continuing rather than an ad interrupting it: the night sky from the
   hero, the same paper-cut wave used between the page's bands, and the
   story's own artwork mark sitting where a storyteller would pause.
   ========================================================================== */
.kk-endcard {
    position: fixed; inset: 0; z-index: 300;
    display: grid; place-items: center;
    padding: 20px;
}
.kk-endcard[hidden] { display: none; }
.kk-noscroll { overflow: hidden; }

.kk-endcard__veil {
    position: absolute; inset: 0;
    background: rgba(28, 13, 11, .62);
    backdrop-filter: blur(4px);
    opacity: 0; transition: opacity .28s ease;
}
.kk-endcard.is-open .kk-endcard__veil { opacity: 1; }

.kk-endcard__card {
    position: relative;
    width: min(440px, 100%);
    max-height: min(92vh, 880px);
    overflow-y: auto;
    background: var(--kk-cream);
    border-radius: var(--kk-radius-lg);
    box-shadow: 0 30px 70px rgba(28, 13, 11, .5);
    opacity: 0; transform: translateY(26px) scale(.93);
    /* A little overshoot on the way in - the card should land like a
       storybook being set down, not slide in like a banner. */
    transition: opacity .3s ease, transform .42s cubic-bezier(.16, 1.16, .3, 1);
}
.kk-endcard.is-open .kk-endcard__card { opacity: 1; transform: none; }
.kk-endcard__card:focus { outline: none; } /* focused programmatically on open */

.kk-endcard__x {
    position: absolute; top: 12px; right: 12px; z-index: 3;
    width: 36px; height: 36px; padding: 0; line-height: 1;
    font-size: 1.5rem; font-family: var(--kk-body);
    color: rgba(245, 237, 230, .75);
    background: rgba(255, 248, 240, .13);
    border: 0; border-radius: 50%; cursor: pointer;
    transition: background .18s ease, color .18s ease, transform .18s ease;
}
.kk-endcard__x:hover { background: rgba(255, 248, 240, .26); color: #fff; transform: rotate(90deg); }

/* --- night header ------------------------------------------------------- */
.kk-endcard__top {
    position: relative; isolation: isolate; overflow: hidden;
    background: linear-gradient(165deg, #2B1512 0%, #52281F 58%, #7A4133 100%);
    color: var(--kk-text-light);
    text-align: center;
    padding: 26px 26px 46px;
}
.kk-endcard__sparks { position: absolute; inset: 0; pointer-events: none; z-index: -1; }
.kk-endcard__sparks span {
    position: absolute; border-radius: 50%; background: var(--kk-gold);
    opacity: .3; animation: kk-twinkle 3.6s ease-in-out infinite;
}

.kk-endcard__disc {
    position: relative;
    width: 64px; height: 64px; margin: 0 auto 13px;
    display: grid; place-items: center;
    border-radius: 50%;
    background: rgba(242, 180, 65, .16);
    box-shadow: inset 0 0 0 2px rgba(242, 180, 65, .5);
}
.kk-endcard__discIcon { font-size: 1.75rem; line-height: 1; }
/* One ring easing outward - the visual echo of a sound that just stopped. */
.kk-endcard__discPulse {
    position: absolute; inset: 0; border-radius: 50%;
    border: 2px solid var(--kk-gold);
    animation: kk-ripple 2.6s ease-out infinite;
}
@keyframes kk-ripple {
    0%   { transform: scale(1);    opacity: .55; }
    70%  { transform: scale(1.55); opacity: 0; }
    100% { transform: scale(1.55); opacity: 0; }
}

.kk-endcard__eyebrow {
    font-family: var(--kk-display); font-weight: 700;
    font-size: .72rem; letter-spacing: .14em; text-transform: uppercase;
    color: rgba(245, 237, 230, .58);
    margin: 0 0 10px;
}
.kk-endcard__h { margin: 0; }
.kk-endcard__ml {
    display: block;
    font-family: var(--kk-display);
    font-size: clamp(1.95rem, 7.4vw, 2.45rem);
    font-weight: 800; line-height: 1.15;
    color: var(--kk-gold);
}
.kk-endcard__gloss {
    display: block; margin-top: 4px;
    font-family: var(--kk-body); font-style: italic; font-weight: 400;
    font-size: 1rem; color: rgba(245, 237, 230, .72);
}
.kk-endcard__line {
    margin: 12px auto 0; max-width: 40ch;
    font-size: .95rem; line-height: 1.55;
    color: rgba(245, 237, 230, .88);
}
.kk-endcard__line em { font-style: normal; font-weight: 700; color: #fff; }

.kk-endcard__wave {
    position: absolute; left: 0; bottom: -1px; width: 100%;
    line-height: 0; color: var(--kk-cream); pointer-events: none;
}
.kk-endcard__wave svg { width: 100%; height: 38px; display: block; }

/* --- body --------------------------------------------------------------- */
.kk-endcard__body { padding: 4px 26px 22px; }

.kk-endcard__perks { list-style: none; margin: 0 0 18px; padding: 0; display: grid; gap: 9px; }
.kk-endcard__perks li {
    display: flex; gap: 10px; align-items: flex-start;
    font-size: .92rem; line-height: 1.45; color: var(--kk-text-muted);
}
.kk-endcard__perks strong { color: var(--kk-text); }
/* Check mark drawn from a rotated corner - no icon font, no extra request. */
.kk-endcard__tick {
    flex: none; position: relative;
    width: 21px; height: 21px; margin-top: 2px;
    border-radius: 50%; background: rgba(95, 167, 119, .18);
}
.kk-endcard__tick::after {
    content: ""; position: absolute; left: 7px; top: 4px;
    width: 5px; height: 9px;
    border: solid var(--kk-green); border-width: 0 2.5px 2.5px 0;
    transform: rotate(42deg);
}

.kk-endcard__cta {
    display: flex; align-items: center; gap: 13px;
    padding: 13px 20px; border-radius: var(--kk-radius);
    background: var(--kk-primary); color: #fff; text-decoration: none;
    box-shadow: 0 6px 0 var(--kk-primary-dark);
    transition: transform .18s ease, box-shadow .18s ease;
}
.kk-endcard__cta:hover { transform: translateY(-3px); box-shadow: 0 9px 0 var(--kk-primary-dark); }
.kk-endcard__cta:active { transform: translateY(3px); box-shadow: 0 2px 0 var(--kk-primary-dark); }
.kk-endcard__ctaIcon {
    flex: none; width: 38px; height: 38px; border-radius: 50%;
    display: grid; place-items: center; font-size: .95rem;
    background: rgba(255, 255, 255, .2);
}
.kk-endcard__ctaText { display: block; text-align: left; }
.kk-endcard__ctaText strong { display: block; font-family: var(--kk-display); font-size: 1.06rem; }
.kk-endcard__ctaText small { display: block; font-size: .84rem; color: rgba(255, 255, 255, .82); }

/* Both platforms in the card too. The Apple half is a real download the
   moment an App Store URL exists, and a "tell me when" link until then -
   and on an iPhone, where the Play button is useless, that link leads. */
.kk-endcard__ctas { display: grid; gap: 10px; }
.kk-endcard__ctaIcon svg { width: 20px; height: 20px; display: block; }
.kk-endcard__ctas.is-dual .kk-endcard__cta--ios {
    background: var(--kk-night); box-shadow: 0 6px 0 #150908;
}
.kk-endcard__ctas.is-dual .kk-endcard__cta--ios:hover { box-shadow: 0 9px 0 #150908; }
.kk-endcard__ctas.is-dual .kk-endcard__cta--ios:active { box-shadow: 0 2px 0 #150908; }
.kk-is-ios .kk-endcard__ctas.is-dual .kk-endcard__cta--ios { order: -1; }

.kk-endcard__soon {
    display: flex; align-items: center; justify-content: center; gap: 9px;
    padding: 11px 14px; border-radius: var(--kk-radius);
    border: 1.5px solid var(--kk-divider);
    font-size: .88rem; color: var(--kk-text-muted); text-decoration: none;
    transition: border-color .18s ease, background .18s ease, color .18s ease;
}
.kk-endcard__soon strong { color: var(--kk-text); font-family: var(--kk-display); }
.kk-endcard__soonIcon svg { width: 15px; height: 15px; display: block; }
.kk-endcard__soon:hover { border-color: var(--kk-text-muted); }

/* An iPhone visitor cannot install today, so the notify link is the real
   call to action for them and the Play button steps back. */
.kk-is-ios .kk-endcard__soon {
    order: -1;
    padding: 13px 16px; font-size: .95rem;
    background: var(--kk-night); border-color: transparent; color: var(--kk-text-light);
}
.kk-is-ios .kk-endcard__soon strong { color: #fff; }
.kk-is-ios .kk-endcard__soon .kk-endcard__soonIcon { color: var(--kk-gold); }
.kk-is-ios .kk-endcard__cta--android {
    background: transparent; color: var(--kk-text);
    box-shadow: inset 0 0 0 2px var(--kk-divider);
}
.kk-is-ios .kk-endcard__cta--android:hover,
.kk-is-ios .kk-endcard__cta--android:active {
    transform: none; box-shadow: inset 0 0 0 2px var(--kk-text-muted);
}
.kk-is-ios .kk-endcard__cta--android .kk-endcard__ctaIcon { background: rgba(43, 21, 18, .07); }
.kk-is-ios .kk-endcard__cta--android .kk-endcard__ctaText small { color: var(--kk-text-muted); }

.kk-endcard__ticket {
    display: block; line-height: 1.45;
    margin: 15px 0 0; padding: 9px 14px;
    font-size: .85rem; text-align: center;
    color: var(--kk-night);
    background: rgba(242, 180, 65, .18);
    border: 1.5px dashed rgba(242, 180, 65, .85);
    border-radius: var(--kk-radius);
}
.kk-endcard__ticket strong { font-family: var(--kk-display); }

.kk-endcard__plans {
    margin: 13px 0 0; text-align: center;
    font-size: .87rem; color: var(--kk-text-muted);
}
.kk-endcard__plans a { color: var(--kk-primary-dark); }

.kk-endcard__later {
    display: block; margin: 11px auto 0; padding: 6px 10px;
    background: none; border: 0; cursor: pointer;
    font-family: var(--kk-body); font-size: .87rem;
    color: var(--kk-text-muted); text-decoration: underline;
    text-underline-offset: 3px;
}
.kk-endcard__later:hover { color: var(--kk-text); }

@media (max-width: 420px) {
    .kk-endcard { padding: 12px; }
    .kk-endcard__top { padding: 24px 20px 42px; }
    .kk-endcard__body { padding: 4px 20px 20px; }
}

/* Short viewports - most phones, and a laptop with a small browser window.
   Everything from the headline down to "Maybe later" has to be reachable
   without scrolling inside the card, so the header gives up the space. */
@media (max-height: 880px) {
    .kk-endcard__top { padding-top: 20px; padding-bottom: 38px; }
    .kk-endcard__disc { width: 54px; height: 54px; margin-bottom: 10px; }
    .kk-endcard__discIcon { font-size: 1.5rem; }
    .kk-endcard__ml { font-size: clamp(1.8rem, 6.6vw, 2.2rem); }
    .kk-endcard__line { margin-top: 9px; font-size: .92rem; }
    .kk-endcard__perks { gap: 8px; margin-bottom: 15px; }
}

@media (prefers-reduced-motion: reduce) {
    .kk-endcard__card, .kk-endcard__veil { transition: none; }
    .kk-endcard__discPulse, .kk-endcard__sparks span { animation: none; }
    .kk-endcard__x:hover { transform: none; }
}


/* ==========================================================================
   Offers band - the app's own promotion artwork (Connect plugin)

   The images are whatever shape they were drawn in, so nothing is cropped
   to a ratio: an offer with a price in the corner has to arrive intact.
   ========================================================================== */
.kk-offers { position: relative; }
.kk-offers__track {
    display: flex; gap: 20px;
    overflow-x: auto; scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    padding: 4px 4px 14px;
    scrollbar-width: none;
}
.kk-offers__track::-webkit-scrollbar { display: none; }

.kk-offer {
    flex: 0 0 100%; scroll-snap-align: start;
    border-radius: var(--kk-radius-lg); overflow: hidden;
    box-shadow: var(--kk-shadow);
    transition: transform .3s ease, box-shadow .3s ease;
    background: var(--kk-muted);
}
.kk-offer:hover { transform: translateY(-5px); box-shadow: var(--kk-shadow-lift); }
.kk-offer img { width: 100%; height: auto; display: block; }
@media (min-width: 760px) { .kk-offer { flex-basis: calc(50% - 10px); } }
/* 52% meant two offers did not quite fit, so the track scrolled a little and
   left a gap down the left-hand side that read as a broken layout. Half the
   width minus half the gap makes exactly two fit, with nothing to scroll. A
   third offer still scrolls, which is what the arrows are for. */

/* Controls sit UNDER the artwork, in one row with the dots. Floated over
   the banners - the usual arrangement - they covered the offer's own
   headline, which is the one thing the banner exists to show. */
.kk-offers__nav {
    order: 0;
    width: 38px; height: 38px; padding: 0; border: 0; border-radius: 50%; cursor: pointer;
    background: var(--kk-surface); box-shadow: var(--kk-shadow);
    display: none; place-items: center;
    transition: transform .18s ease, background .18s ease;
}
.kk-offers.is-scrollable .kk-offers__nav { display: grid; }
.kk-offers__nav:hover { transform: scale(1.1); }
.kk-offers__nav::before {
    content: ""; width: 9px; height: 9px;
    border: solid var(--kk-text); border-width: 0 2.5px 2.5px 0;
}
.kk-offers__nav--prev::before { transform: rotate(135deg); margin-left: 3px; }
.kk-offers__nav--next::before { transform: rotate(-45deg); margin-right: 3px; }

.kk-offers__controls { display: flex; align-items: center; justify-content: center; gap: 14px; margin-top: 8px; }
.kk-offers__dots { display: flex; justify-content: center; gap: 8px; }
.kk-offers__dot {
    width: 9px; height: 9px; padding: 0; border: 0; border-radius: 50%; cursor: pointer;
    background: var(--kk-divider); transition: background .2s ease, transform .2s ease, width .2s ease;
}
.kk-offers__dot.is-on { background: var(--kk-primary); width: 24px; border-radius: var(--kk-radius-pill); }


/* ==========================================================================
   Featured story banners
   ========================================================================== */
.kk-featured { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 22px; }
.kk-featured__item {
    position: relative; display: block; overflow: hidden;
    border-radius: var(--kk-radius-lg); box-shadow: var(--kk-shadow);
    text-decoration: none; color: #fff;
    transition: transform .3s ease, box-shadow .3s ease;
}
.kk-featured__item:hover { transform: translateY(-6px); box-shadow: var(--kk-shadow-lift); }
.kk-featured__item img { width: 100%; height: auto; display: block; transition: transform .5s ease; }
.kk-featured__item:hover img { transform: scale(1.04); }
.kk-featured__veil {
    position: absolute; inset: 0;
    background: linear-gradient(to top, rgba(28, 13, 11, .8) 0%, rgba(28, 13, 11, .12) 55%, transparent 80%);
}
.kk-featured__copy { position: absolute; left: 20px; right: 20px; bottom: 16px; }
.kk-featured__meta {
    display: block; font-size: .76rem; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase; color: var(--kk-gold);
    margin-bottom: 3px;
}
.kk-featured__copy strong { font-family: var(--kk-display); font-size: 1.25rem; line-height: 1.2; }


/* ==========================================================================
   Contact form (Connect plugin)
   ========================================================================== */
.kk-form-wrap {
    background: var(--kk-surface); border-radius: var(--kk-radius-lg);
    padding: clamp(24px, 4vw, 38px); box-shadow: var(--kk-shadow);
    margin: 32px 0;
}
.kk-form__title { font-size: 1.5rem; margin-bottom: 8px; }
.kk-form { margin-top: 20px; }
.kk-form__row { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
@media (max-width: 620px) { .kk-form__row { grid-template-columns: 1fr; gap: 0; } }

.kk-field { margin: 0 0 18px; }
.kk-field label {
    display: block; margin-bottom: 6px;
    font-family: var(--kk-display); font-weight: 700; font-size: .93rem; color: var(--kk-text);
}
.kk-field label span[aria-hidden] { color: var(--kk-primary); }
.kk-field__opt { font-family: var(--kk-body); font-weight: 400; color: var(--kk-text-muted); }
.kk-field input, .kk-field select, .kk-field textarea {
    width: 100%; font: inherit; color: var(--kk-text);
    background: var(--kk-cream);
    border: 2px solid var(--kk-divider); border-radius: 16px;
    padding: 13px 16px;
    transition: border-color .18s ease, background .18s ease, box-shadow .18s ease;
}
.kk-field textarea { resize: vertical; min-height: 130px; }
.kk-field select {
    appearance: none;
    /* Chevron drawn into the field, so the select matches the inputs on
       every platform instead of inheriting the OS widget. */
    background-image: linear-gradient(45deg, transparent 50%, var(--kk-text-muted) 50%),
                      linear-gradient(135deg, var(--kk-text-muted) 50%, transparent 50%);
    background-position: calc(100% - 21px) 22px, calc(100% - 15px) 22px;
    background-size: 6px 6px, 6px 6px;
    background-repeat: no-repeat;
    padding-right: 42px;
}
.kk-field input:focus, .kk-field select:focus, .kk-field textarea:focus {
    outline: none; background: var(--kk-surface);
    border-color: var(--kk-primary-light);
    box-shadow: 0 0 0 4px rgba(232, 93, 78, .14);
}
.kk-field .has-error { border-color: var(--kk-primary); background: rgba(232, 93, 78, .05); }

/* Off-screen rather than display:none - some bots skip hidden inputs. */
.kk-form__hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.kk-form__foot { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; }
.kk-form__note { font-size: .85rem; color: var(--kk-text-muted); flex: 1 1 220px; }
.kk-form__submit.is-sending { opacity: .75; cursor: progress; }
.kk-form__live { margin: 14px 0 0; font-size: .9rem; color: var(--kk-text-muted); }
.kk-form__live.is-error { color: var(--kk-primary-dark); font-weight: 700; }
.kk-form__error {
    background: rgba(232, 93, 78, .1); border-radius: 16px;
    padding: 14px 18px; font-size: .95rem;
}

/* Confirmation. Deliberately generous - the moment someone has just told
   you something is wrong is not the moment for a grey one-line toast. */
.kk-form__done { text-align: center; padding: 26px 10px; }
.kk-form__done h4 { font-size: 1.4rem; margin-bottom: 8px; }
.kk-form__done p { color: var(--kk-text-muted); max-width: 40ch; margin-inline: auto; }
.kk-form__doneMark {
    position: relative; display: block; width: 64px; height: 64px;
    margin: 0 auto 18px; border-radius: 50%;
    background: rgba(95, 167, 119, .16);
    animation: kk-pop .5s cubic-bezier(.2, 1.3, .4, 1) both;
}
.kk-form__doneMark::after {
    content: ""; position: absolute; left: 24px; top: 16px;
    width: 13px; height: 26px;
    border: solid var(--kk-green); border-width: 0 4px 4px 0;
    transform: rotate(42deg);
    animation: kk-tick .35s ease .2s both;
}
@keyframes kk-pop  { from { transform: scale(.5); opacity: 0; } to { transform: scale(1); opacity: 1; } }
@keyframes kk-tick { from { opacity: 0; transform: rotate(42deg) scale(.4); } to { opacity: 1; transform: rotate(42deg) scale(1); } }


/* ==========================================================================
   WhatsApp (Connect plugin)
   ========================================================================== */
.kk-wa { position: fixed; right: 20px; bottom: 20px; z-index: 200; }
/* Out of the way while the end-of-sample card is open. */
.kk-noscroll .kk-wa { opacity: 0; pointer-events: none; }

.kk-wa__btn {
    position: relative; display: grid; place-items: center;
    width: 58px; height: 58px; border-radius: 50%;
    background: #25D366; color: #fff;
    box-shadow: 0 10px 26px rgba(37, 211, 102, .42);
    transition: transform .2s ease, box-shadow .2s ease;
}
.kk-wa__btn:hover { transform: scale(1.07); box-shadow: 0 14px 32px rgba(37, 211, 102, .55); }
.kk-wa__glyph { width: 32px; height: 32px; }

/* One slow ring. Enough to be noticed on a first visit, not enough to
   nag - and gone entirely for anyone who has asked for less motion. */
.kk-wa__ping {
    position: absolute; inset: 0; border-radius: 50%;
    border: 2px solid #25D366;
    animation: kk-ripple 2.8s ease-out infinite;
}

.kk-wa__bubble {
    position: absolute; right: 0; bottom: 72px;
    width: max-content; max-width: min(260px, calc(100vw - 48px));
    background: var(--kk-surface); color: var(--kk-text);
    border-radius: 18px 18px 4px 18px;
    padding: 14px 34px 14px 16px;
    box-shadow: var(--kk-shadow-lift);
    cursor: pointer;
    opacity: 0; transform: translateY(8px) scale(.96); transform-origin: bottom right;
    transition: opacity .3s ease, transform .35s cubic-bezier(.16, 1.16, .3, 1);
}
.kk-wa.has-bubble .kk-wa__bubble { opacity: 1; transform: none; }
.kk-wa__bubble strong { display: block; font-family: var(--kk-display); font-size: 1rem; }
.kk-wa__bubble span { display: block; font-size: .84rem; color: var(--kk-text-muted); margin-top: 2px; }
.kk-wa__bubbleX {
    position: absolute; top: 6px; right: 8px;
    width: 24px; height: 24px; padding: 0; line-height: 1;
    background: none; border: 0; cursor: pointer;
    font-size: 1.2rem; color: var(--kk-text-muted);
}
.kk-wa__bubbleX:hover { color: var(--kk-text); }

@media (max-width: 620px) {
    .kk-wa { right: 14px; bottom: 14px; }
    .kk-wa__btn { width: 54px; height: 54px; }
}

/* The Contact page's own WhatsApp block */
.kk-wacard {
    display: flex; align-items: center; gap: 16px;
    background: linear-gradient(135deg, #25D366 0%, #128C7E 100%);
    color: #fff; text-decoration: none;
    border-radius: var(--kk-radius-lg);
    padding: 18px 22px; margin: 26px 0;
    box-shadow: 0 12px 30px rgba(18, 140, 126, .3);
    transition: transform .2s ease, box-shadow .2s ease;
}
.kk-wacard:hover { transform: translateY(-3px); box-shadow: 0 18px 38px rgba(18, 140, 126, .4); }
.kk-wacard__icon {
    flex: none; display: grid; place-items: center;
    width: 48px; height: 48px; border-radius: 50%;
    background: rgba(255, 255, 255, .2);
}
.kk-wacard__glyph { width: 28px; height: 28px; }
.kk-wacard__text { flex: 1; }
.kk-wacard__text strong { display: block; font-family: var(--kk-display); font-size: 1.15rem; }
.kk-wacard__text span { display: block; font-size: .88rem; color: rgba(255, 255, 255, .85); }
.kk-wacard__go { font-size: 1.3rem; transition: transform .2s ease; }
.kk-wacard:hover .kk-wacard__go { transform: translateX(4px); }
@media (max-width: 520px) {
    .kk-wacard { flex-wrap: wrap; }
    .kk-wacard__go { display: none; }
}


/* ==========================================================================
   Category ribbon - what is actually inside the app, drifting past

   Live from the backend, in both scripts. Two identical rows scroll as one
   so the loop never snaps back; the second is hidden from screen readers so
   the names are not read out twice.
   ========================================================================== */
.kk-ribbon-band {
    overflow: hidden;
    padding: 26px 0 22px;
    background: linear-gradient(180deg, var(--kk-cream) 0%, var(--kk-muted) 100%);
    border-bottom: 1px solid var(--kk-divider);
}
.kk-ribbon { display: flex; width: max-content; }
.kk-ribbon__row { display: flex; gap: 14px; padding-right: 14px; animation: kk-drift-x 46s linear infinite; }
.kk-ribbon:hover .kk-ribbon__row { animation-play-state: paused; }
@keyframes kk-drift-x { from { transform: translateX(0); } to { transform: translateX(-100%); } }

.kk-chip {
    display: inline-flex; align-items: center; gap: 9px; flex: none;
    padding: 10px 18px; border-radius: var(--kk-radius-pill);
    background: var(--kk-surface); text-decoration: none;
    box-shadow: 0 4px 14px rgba(43, 21, 18, .07);
    border: 2px solid transparent;
    transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
.kk-chip:hover { transform: translateY(-3px); box-shadow: var(--kk-shadow); }
.kk-chip__icon { font-size: 1.05rem; line-height: 1; }
.kk-chip__name { font-family: var(--kk-display); font-weight: 700; font-size: .96rem; color: var(--kk-text); }
.kk-chip__ml { font-size: .9rem; color: var(--kk-text-muted); }
.kk-chip--story        { border-color: rgba(232, 93, 78, .35); }
.kk-chip--song         { border-color: rgba(242, 180, 65, .5); }
.kk-chip--book_reading { border-color: rgba(74, 155, 142, .4); }
.kk-chip--mindfulness  { border-color: rgba(156, 137, 184, .45); }
.kk-chip--story:hover        { border-color: var(--kk-primary); }
.kk-chip--song:hover         { border-color: var(--kk-gold); }
.kk-chip--book_reading:hover { border-color: var(--kk-teal); }
.kk-chip--mindfulness:hover  { border-color: var(--kk-lavender); }

@media (prefers-reduced-motion: reduce) {
    .kk-ribbon__row { animation: none; }
    .kk-ribbon { overflow-x: auto; width: 100%; }
    .kk-ribbon__row[aria-hidden="true"] { display: none; }
}

/* ==========================================================================
   v3 fill-ins and overrides

   Everything above this line is either the new design layer or the carried-
   forward component layer. This block is the seam: the handful of small
   pieces the redesign needs on top, kept together so the difference between
   "inherited" and "changed for v3" is never in doubt.
   ========================================================================== */

/* The brand lockup in the header. */
.kk-brand__mark { flex: none; display: block; width: 40px; height: 40px; }
.kk-brand__text { display: block; line-height: 1.1; }
.kk-footer__logo { max-height: 62px; width: auto; }

/* Featured banners sit above the story shelf and need air under them. */
.kk-featured-wrap { margin-bottom: clamp(22px, 3vw, 38px); }

/* The category ribbon now crosses the seam between the night hero and the
   morning, so its chips sit on cream rather than on the old warm band. The
   inherited rules assume a cream ground already; these only firm up the
   contrast of the Malayalam half, which was set light enough to disappear
   against the new, brighter background. */
.kk-ribbon-band .kk-chip__ml { color: var(--kk-text-muted); }
.kk-ribbon-band .kk-chip { border-color: var(--kk-divider); }

/* Story cards: the inherited card is good, but its radius and shadow were
   tuned to the old, softer palette. */
.kk-card { border-radius: var(--kk-radius); }
.kk-card:hover { box-shadow: var(--kk-shadow); }
.kk-card__title { font-family: var(--kk-display); }

/* Pricing cards inherit their layout; only the emphasis changes, because the
   popular plan has to survive on a warmer ground than before. */
.kk-price-card--popular { border-color: var(--kk-primary); }

/* The WhatsApp bubble is fixed to the viewport and would otherwise sit over
   the footer's last row on a phone. */
@media (max-width: 640px) {
    .kk-footer { padding-bottom: 96px; }
}

/* The end-of-sample card is a full-screen overlay; it must clear the sticky
   header, which is now translucent rather than solid. */
.kk-endcard { z-index: 200; }

/* Two covers across on a phone rather than one.
   The inherited grid asks for a 215px minimum, which on a 390px screen
   resolves to a single column - eight cards then become a 3,700px scroll of
   one picture after another, and the shelf stops reading as a shelf. The
   app's own home screen shows two across; the website should agree with it. */
@media (max-width: 560px) {
    .kk-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
    .kk-card__body { padding: 12px 12px 15px; }
    .kk-card__title { font-size: .95rem; }
    .kk-card__meta { font-size: .74rem; }

    /* Both marks on the artwork, in proportion to a two-up card.
       At the desktop size the Apple's Choice pill came out 102px wide on a
       169px card - sixty per cent of the artwork - so it read as the subject
       of the card rather than as a mark on it. The Free/Premium tag had the
       same problem at the other corner. Same pills, same colours, scaled to
       the card they are actually sitting on. */
    .kk-card__ribbon {
        font-size: .6rem;
        padding: 3px 8px;
        bottom: 8px;
        left: 8px;
        max-width: calc(100% - 16px);
    }
    .kk-card__tag {
        font-size: .6rem;
        padding: 3px 8px;
        top: 8px;
        right: 8px;
    }
}

/* ==========================================================================
   v3.1 — corrections from the live site, 2026-09-10
   ========================================================================== */

/* --- the brand mark is now the app's own icon --------------------------- */
.kk-brand__mark {
    flex: none;
    width: 40px;
    height: 40px;
    /* The icon file is a full square - that is what the app stores require -
       so the rounded corner is applied here. A ratio rather than a fixed
       radius, so it stays proportional if the mark is ever shown larger. */
    border-radius: 23%;
    display: block;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .28);
}

/* --- store badges: two badges, one shape --------------------------------
   The iOS badge carried "Tell me when it's ready" as a third line inside its
   text stack, so it was taller AND wider than the Play badge sitting next to
   it. Two badges of different sizes in the same row read as a mistake, and it
   happened in both places they appear.

   Fixed by making the two structurally identical - logo, small line, strong
   line, nothing else - and lifting the nudge out of the flow into a corner
   tag. Both badges now share a fixed height and a fixed minimum width, so
   they cannot drift apart again whatever text goes in them. */
.kk-store-badges {
    align-items: stretch;
    padding-top: 10px;      /* room for the corner tag to sit above the pill */
    gap: 20px 13px;
}

/* --- both badges on one line, everywhere -------------------------------
   The two are a pair: "here is where you get it". Stacked, they read as two
   separate offers, and the second one looks like an afterthought. So they
   share a row and split it evenly, at whatever width the row happens to be.

   `flex: 1 1 0` with `min-width: 0` is what makes that work: equal shares of
   the row, and neither one allowed to push past its share because its text
   is longer. The fixed min-width from above has to be cancelled or the pair
   wraps again the moment the container is under ~430px - which is exactly
   what the footer column is. */
.kk-store-badges { flex-wrap: nowrap; }
.kk-store-badge {
    flex: 1 1 0;
    min-width: 0;
    max-width: 205px;
}
.kk-store-badge__text { min-width: 0; }
.kk-store-badge__text small,
.kk-store-badge__text strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* In the footer the row is about a third the width, so the pair scales down
   together rather than one of them dropping to the next line. */
.kk-footer .kk-store-badges { gap: 10px; padding-top: 0; }
.kk-footer .kk-store-badge { height: 48px; padding: 0 11px; gap: 7px; max-width: 178px; }
.kk-footer .kk-store-badge__logo { width: 18px; height: 18px; }
.kk-footer .kk-store-badge__text small { font-size: .54rem; letter-spacing: .04em; }
.kk-footer .kk-store-badge__text strong { font-size: .82rem; }
/* The corner tag is wider than a footer-sized badge, so it only appears in
   the download band, where there is room for it. The badge still links to
   the same place. */
.kk-footer .kk-store-badge__nudge { display: none; }
.kk-store-badge {
    /* Width comes from the flex rules below, not from a fixed minimum - a
       208px floor here beat them and pushed the pair out of the footer
       column. Height and padding are what has to match between the two.

       Sized down 2026-09-10 (Unni: "make sure the badges are not oversized,
       it should be medium"). 64px tall and 260 wide made them compete with
       the headline above them; a store badge is a signpost, not a hero. */
    min-width: 0;
    height: 54px;
    padding: 0 16px;
    gap: 9px;
    box-sizing: border-box;
    justify-content: flex-start;
}
.kk-store-badge__logo { width: 22px; height: 22px; }
.kk-store-badge__text small { font-size: .6rem; }
.kk-store-badge__text strong { font-size: .95rem; }
.kk-store-badge__text { display: flex; flex-direction: column; justify-content: center; }
.kk-store-badge__nudge {
    position: absolute;
    top: -9px;
    right: 12px;
    margin: 0;
    font-size: .55rem;
    padding: 2px 8px;
    line-height: 1.5;
    box-shadow: 0 3px 8px rgba(34, 30, 51, .28);
}
@media (max-width: 560px) {
    /* Still one row on a phone - just a smaller one. Below this the logo is
       dropped rather than the row broken: at 390px two badges have about
       165px each, and the two lines of text are worth more than the mark. */
    .kk-store-badges { width: 100%; gap: 9px; }
    .kk-store-badge { height: 48px; padding: 0 11px; gap: 7px; max-width: none; }
    .kk-store-badge__logo { width: 18px; height: 18px; }
    .kk-store-badge__text small { font-size: .54rem; }
    .kk-store-badge__text strong { font-size: .8rem; }
    .kk-store-badge__nudge { display: none; }
}
@media (max-width: 400px) {
    .kk-store-badge__logo { display: none; }
}

/* --- the hero video, fitted to the phone --------------------------------
   The intro video is not the shape of a phone screen. Forced into a 9:19.5
   frame with `cover` it was cropped hard on both sides - the words "Katha
   Kutty" ran off the edge, which is a poor thing for a brand video to do.

   v3.2 solved that by letting the FRAME take the video's shape. That fixed
   the cropping and broke something more important: with a landscape clip the
   phone collapsed into a short squat box, and the phone is the thing a
   visitor actually recognises.

   So the frame is fixed at 9:19.5 again, and the video is CONTAINED inside
   it - whole, centred, nothing cropped - with a blurred copy of the poster
   filling the space above and below. The phone stays a phone, and the video
   still arrives intact. */
.kk-phone__screen {
    /* ALWAYS a tall phone. 9:19.5, fixed.
       v3.2 let the frame take the video's own shape, which was the wrong
       trade: a landscape intro video collapsed the frame to 0.8 and the hero
       became a squat little box with a notch on it. The phone is the thing
       people recognise; the video is what has to fit inside it, not the other
       way round. */
    aspect-ratio: 9 / 19.5;
    background: linear-gradient(180deg, #1B1738 0%, #0B0A1A 100%);
}
.kk-phone__screen > video,
.kk-phone__screen > img {
    object-fit: contain;
    object-position: center;
}
/* The blurred backdrop that fills the letterbox when the video is a
   different shape from its frame. It is the poster image, scaled up and
   blurred - one image, no second video decode. */
.kk-phone__backdrop {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transform: scale(1.3);
    /* Bright enough to read as the video's own world continuing past its
       edges, dark enough that the video is still clearly the subject. Too
       dark and the phone looks half-empty; too light and the eye cannot tell
       where the video stops. */
    filter: blur(30px) saturate(1.3) brightness(.78);
    z-index: 0;
    pointer-events: none;
}
/* A soft vignette over the backdrop, so the letterbox falls away at the top
   and bottom of the screen instead of ending on a hard line. */
.kk-phone__screen::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    background: linear-gradient(180deg, rgba(11,10,26,.55) 0%, transparent 22%,
                                        transparent 78%, rgba(11,10,26,.65) 100%);
}
.kk-phone__screen > video { position: relative; z-index: 1; }

/* (the mock app screens are the same shape as the hero phone - one rule now
   covers both, since the hero no longer changes shape) */


/* ==========================================================================
   Tap targets on touch screens
   (added 2026-09-11 after auditing the phone rendering)

   Three controls were under 36px on a phone: the "Inside the app" dots at
   9x9, the footer menu links at 24px tall, and the footer contact and policy
   links at 19px. All three are easy to miss with a thumb, and the policy
   links are the ones a Play reviewer taps.

   Nothing here changes how anything LOOKS - the dots keep their 9px shape and
   the links their spacing. Only the area that responds to a touch grows, and
   only on touch devices, so the desktop layout is untouched.
   ========================================================================== */
@media (hover: none) and (pointer: coarse) {
    /* The dot stays 9px; an invisible box around it catches the thumb. */
    .kk-dot { position: relative; }
    .kk-dot::after {
        content: '';
        position: absolute;
        inset: -14px -9px;
    }

    /* Padding is invisible, so the footer reads the same and answers to a
       thumb. The gap is reduced by the same amount the padding adds, so the
       rhythm of the list does not change either. */
    .kk-footer ul { gap: 0; }
    .kk-footer__col ul a,
    .kk-footer__menu .kk-menu a {
        display: block;
        padding-block: 9px;
    }
}
