/* ============================================================
   KompanyOS — 3 Sided Cube UI components (shared, reusable)
   The design-system component library: buttons, links, cards, callout,
   badges/chips, form fields, quote, stats, icon, dashed card. Self-contained —
   each colour/font reads the 3SC token when present (--cube-*), falls back to
   the experience-page token (--pink/--green/…), then to a brand hex — so a
   component renders correctly on any page, with or without a token set.

   Used by styles.html (the catalog) AND the experience pages. Demos-only
   layout (rows/grids, swatches, type/shadow specimens) stays in styles.html.
   ============================================================ */

/* ---------- Buttons + link ---------- */
/* ============================================================
   .cube-btn — matched to the website's PressButton
   3sidedcube/3sc-website · src/components/elements/Buttons/PressButton

   Their spec, verbatim:
     base      "interactive rounded-none px-4 py-2 font-bold inline-flex
                items-center justify-center relative uppercase"
     style     border: BORDER.m solid COLORS.neutral.black   -> 3px solid #000
               boxShadow: SHADOW.m                           -> 4px 4px 0 #000
               transition: all .1s cubic-bezier(.175,.885,.32,1.275)
     whileHover ANIMATION["Animation-Button"].hover  -> y:-2, shadow 5px
     whileTap   ANIMATION["Animation-Button"].tap    -> y:+2 x:+2, shadow 1px,
                                                        duration .1 easeIn
     variants  primary green/black · secondary pink/white · yellow · purple ·
               white · black-rounded (radius .5rem, SHADOW.mLight)

   Square corners, no tilt, and the lift/press is theirs rather than this
   repo's rotate-and-grow. Default is their default: primary green.
   ============================================================ */
.cube-btn {
  display: inline-flex; align-items: center; justify-content: center;
  position: relative; cursor: pointer; gap: 1rem;
  font-family: var(--cube-font-primary, var(--font, 'Poppins', system-ui, sans-serif));
  font-weight: 700; font-size: 1rem; line-height: 1.5; letter-spacing: 0.025em;
  text-transform: uppercase; text-decoration: none;
  padding: .5rem 1rem;
  border-radius: 0;
  border: var(--cube-border-m, 3px) solid var(--cube-black, #000);
  background: var(--cube-green, #00ed71);
  color: var(--cube-black, #000);
  box-shadow: var(--cube-shadow-m, 4px 4px 0 0 rgba(0,0,0,1));
  /* Hover/return uses a CSS linear() easing sampled from the 3SC PressButton's
     framer-motion spring (type:spring, stiffness:500, damping:30). Measured on the
     real component: y rises, overshoots to -2.10px at ~208ms, settles by ~340ms.
     A plain CSS transition (the old `.1s cubic-bezier`) can't reproduce a JS
     spring — linear() can, so the hover now matches. Tap is a fast easeIn (below),
     as in framer (whileTap: duration .1, easeIn). */
  --cube-spring: linear(0, 0.025, 0.18, 0.41, 0.63, 0.82, 0.955, 1.02, 1.048, 1.05, 1.042, 1.03, 1.018, 1.005, 1);
  transition: transform .35s var(--cube-spring), box-shadow .35s var(--cube-spring);
}
/* the arrow is their brand asset (src/assets/icons/arrow.svg) — a solid block
   arrow, not a thin stroked line. Applied as a mask so it inherits
   currentColor exactly like their fill="currentColor", which also means no
   per-variant invert() hacks.
   OPT-IN only (add `.arrow`): the base 3SC PressButton has NO arrow, so plain
   .cube-btn matches it. 3SC adds an arrow only in specific CTAs (ButtonSection). */
.cube-btn.arrow::after {
  content: ""; flex: none; width: 1.375em; height: 1.26em;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='22' viewBox='0 0 24 22'><path d='M11.8183 0.140625L9.80262 2.0542L17.7795 9.64062H0.381836V12.3549H17.7795L9.80262 19.9413L11.8183 21.8549L23.2547 10.9978L11.8183 0.140625Z'/></svg>") center/contain no-repeat;
          mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='22' viewBox='0 0 24 22'><path d='M11.8183 0.140625L9.80262 2.0542L17.7795 9.64062H0.381836V12.3549H17.7795L9.80262 19.9413L11.8183 21.8549L23.2547 10.9978L11.8183 0.140625Z'/></svg>") center/contain no-repeat;
}
.cube-btn:hover { transform: translateY(-2px); box-shadow: var(--cube-lift-shadow, 5px 5px 0 0 rgba(0,0,0,1)); }
.cube-btn:active { transform: translate(2px, 2px); box-shadow: var(--cube-press-shadow, 1px 1px 0 0 rgba(0,0,0,1)); transition: transform .1s ease-in, box-shadow .1s ease-in; }

/* ---- their variants ---- */
.cube-btn.pink,
.cube-btn.secondary { background: var(--cube-pink, #f70087); color: var(--cube-white, #fff); }
.cube-btn.yellow    { background: var(--cube-yellow, #ffd100); color: var(--cube-black, #000); }
.cube-btn.purple    { background: var(--cube-purple, #9747ff); color: var(--cube-white, #fff); }
.cube-btn.white     { background: var(--cube-white, #fff); color: var(--cube-black, #000); }
.cube-btn.black     { background: var(--cube-black, #000); color: var(--cube-white, #fff); }
.cube-btn.black-rounded {
  background: var(--cube-black, #000); color: var(--cube-white, #fff);
  border-radius: .5rem; box-shadow: var(--cube-shadow-m-light, 4px 4px 0 0 rgba(0,0,0,.2));
}
/* kept for the pages that use it: transparent, black ink */
.cube-btn.ghost { background: transparent; color: var(--cube-ink, #0a0a0a); }
.cube-btn.green { background: var(--cube-green, #00ed71); color: var(--cube-black, #000); }

/* ---- sizes: their p-2 / p-5, and their typography variants ---- */
.cube-btn.sm { font-size: .8125rem; padding: .5rem .75rem; gap: .625rem; box-shadow: var(--cube-shadow-s, 3px 3px 0 0 rgba(0,0,0,1)); }
.cube-btn.sm::after { width: 1.125em; height: 1.125em; }
.cube-btn.lg { font-size: 1.25rem; padding: 1.25rem; gap: 1.75rem; justify-content: space-between; }
.cube-btn.no-arrow { }



.cube-link {
  font-family: var(--cube-font-primary, var(--font, 'Poppins', system-ui, sans-serif));
  font-weight: 700; font-size: 18px; color: var(--ink, #000); text-decoration: none; padding-bottom: 2px;
  background: linear-gradient(180deg, transparent 75%, var(--cube-yellow, var(--yellow, #ffd100)) 75%, var(--cube-yellow, var(--yellow, #ffd100)) 98%, transparent 98%);
  background-size: 0% 100%; background-repeat: no-repeat; transition: background-size .3s ease;
}
.cube-link:hover { background-size: 100% 100%; }

/* ---------- Card ---------- */
.ds-card {
  background: #fff; border: 3px solid #000; box-shadow: var(--cube-shadow, 10px 10px 0 0 #000);
  overflow: hidden; display: flex; flex-direction: column;
  transition: box-shadow .2s ease, transform .2s ease;
}
.ds-card:hover { box-shadow: 12px 12px 0 var(--cube-pink, var(--pink, #f70087)); transform: translate(-2px,-2px); }
.ds-card .art {
  aspect-ratio: 16 / 9; background: var(--cube-grad-green, linear-gradient(270deg, #a0ff1f, #00ed71));
  border-bottom: 3px solid #000; position: relative; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  font: 800 40px/1 var(--cube-font-primary, var(--font, 'Poppins', system-ui, sans-serif)); font-style: italic; color: rgba(0,0,0,0.22);
}
.ds-card .art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ds-card .body { padding: 22px 22px 26px; display: flex; flex-direction: column; gap: 14px; flex: 1; }
.ds-card .eyebrow {
  font-family: var(--cube-font-secondary, var(--mono, 'Anonymous Pro', ui-monospace, monospace)); font-size: 12px;
  color: var(--cube-pink, var(--pink, #f70087)); font-weight: 700; text-transform: uppercase; letter-spacing: .15em;
}
.ds-card h3 { font: 700 24px/1.2 var(--cube-font-primary, var(--font, 'Poppins', system-ui, sans-serif)); text-transform: uppercase; letter-spacing: .02em; }
.ds-card p  { font: 400 15px/1.6 var(--cube-font-secondary, var(--mono, 'Anonymous Pro', ui-monospace, monospace)); color: var(--cube-ink, var(--ink, #0a0a0a)); }
.ds-card .foot { margin-top: auto; display: flex; justify-content: space-between; align-items: center; }
.ds-card .foot .cat { font-family: var(--cube-font-secondary, var(--mono, 'Anonymous Pro', ui-monospace, monospace)); font-size: 12px; color: var(--cube-gray-500, var(--gray-500, #5b5b5b)); text-transform: uppercase; letter-spacing: .1em; }
.ds-card .foot .arr { width: 28px; height: 28px; border-radius: 50%; background: #000; color: #fff; display: grid; place-items: center; font-size: 14px; }

/* ---------- Signature callout ---------- */
.callout {
  position: relative; border: 4px solid #000; background: #fff; box-shadow: var(--cube-shadow, 10px 10px 0 0 #000);
  padding: 64px 56px 72px; overflow: hidden; transform: rotate(-0.7deg); max-width: 1060px; margin: 0 auto;
}
.callout .pill {
  position: absolute; top: -20px; left: 56px; background: var(--cube-pink, var(--pink, #f70087)); color: #fff;
  border: 3px solid #000; box-shadow: 4px 4px 0 #000; font-weight: 500; padding: 12px 28px;
  border-radius: 0 14px 14px 14px; transform: rotate(-2.5deg); font-size: 18px;
}
.callout .title { font: italic 800 84px/1 var(--cube-font-primary, var(--font, 'Poppins', system-ui, sans-serif)); margin-bottom: 14px; position: relative; display: inline-block; }
.callout .title .pink-bg { background: var(--cube-pink, var(--pink, #f70087)); color: #fff; padding: 2px 18px 8px; margin-right: 8px; transform: rotate(-1.5deg); display: inline-block; }
.callout .sub { font: 500 24px/1.6 var(--cube-font-primary, var(--font, 'Poppins', system-ui, sans-serif)); max-width: 620px; margin-bottom: 26px; }
/* The marker stroke is measured UP FROM THE FONT'S DESCENT LINE (the bottom of
   the inline box), not as a % of the line box: a percentage puts the band
   somewhere different at every line-height, which is how markers elsewhere on
   the site ended up cutting through the tails of p/y. Same stroke as before at
   this component's 1.6 line-height — it just no longer moves when that changes. */
.callout .sub .hl-y { background: linear-gradient(to top, transparent .12em, var(--cube-yellow, var(--yellow, #ffd100)) .12em, var(--cube-yellow, var(--yellow, #ffd100)) .6em, transparent .6em); font-weight: 700; padding: 0 4px; }
.callout .sticker {
  position: absolute; right: -20px; top: 36px; width: 340px; height: 340px; border-radius: 50%;
  background: #000; display: grid; place-items: center; transform: rotate(4deg); border: 4px solid #000;
  box-shadow: var(--cube-shadow, 10px 10px 0 0 #000); color: #fff;
}
.callout .sticker img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }
.callout .sticker .play { width: 0; height: 0; border-left: 92px solid var(--cube-green, var(--green, #00ed71)); border-top: 56px solid transparent; border-bottom: 56px solid transparent; margin-left: 24px; }
.callout .scribble { font-family: var(--cube-font-secondary, var(--mono, 'Anonymous Pro', ui-monospace, monospace)); font-style: italic; font-size: 20px; position: absolute; bottom: 120px; right: 80px; transform: rotate(10deg); }
.callout .arrow {
  position: absolute; bottom: 70px; right: 180px; width: 70px; height: 70px; transform: rotate(-15deg);
  background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 70 70'><path fill='%235b5b5b' d='M12 58c5-2 20-10 34-26 6-7 14-19 17-27 1-2 3-2 3 0 0 8-8 21-18 32C36 49 20 60 4 63c-1 0-2-1-1-2 2-1 6-2 9-3z'/></svg>") center/contain no-repeat;
}
@media (max-width: 900px) { .callout .sticker, .callout .scribble, .callout .arrow { display: none; } }

/* ---------- Badges + category chips ---------- */
.cube-badge {
  border: 3px solid #000; padding: 10px 22px; box-shadow: var(--cube-shadow-sm, var(--shadow-sm, 4px 4px 0 0 #000));
  font-family: var(--cube-font-primary, var(--font, 'Poppins', system-ui, sans-serif)); font-weight: 600; font-size: 15px;
  letter-spacing: .02em; border-radius: 0 14px 14px 14px; display: inline-block; transform: rotate(-2deg);
}
.cube-badge.pink   { background: var(--cube-pink, var(--pink, #f70087)); color: #fff; }
.cube-badge.green  { background: var(--cube-green, var(--green, #00ed71)); color: #000; }
.cube-badge.yellow { background: var(--cube-yellow, var(--yellow, #ffd100)); color: #000; }
.cube-badge.black  { background: #000; color: #fff; }
.cube-badge.white  { background: #fff; color: #000; }

.cat-chip {
  font-family: var(--cube-font-secondary, var(--mono, 'Anonymous Pro', ui-monospace, monospace)); font-size: 12px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .12em; border: 2px solid #000; padding: 4px 10px 5px; background: #fff;
  display: inline-block; margin-right: 8px;
}
.cat-chip.blue   { background: var(--cube-cat-blue, #00a3ff); color: #000; }
.cat-chip.teal   { background: var(--cube-cat-teal, #00d4b2); color: #000; }
.cat-chip.orange { background: var(--cube-cat-orange, #ff7a00); color: #000; }
.cat-chip.lime   { background: var(--cube-cat-lime, #aeee00); color: #000; }

/* ---------- Dashed utility card ---------- */
.dashed-card {
  border: 3px dashed #000; border-radius: 12px; padding: 28px 32px; background: #fff;
  font-family: var(--cube-font-secondary, var(--mono, 'Anonymous Pro', ui-monospace, monospace)); font-size: 15px; line-height: 1.6; max-width: 520px;
}

/* ---------- Form fields ---------- */
.cube-field label { display: block; font-family: var(--cube-font-primary, var(--font, 'Poppins', system-ui, sans-serif)); font-weight: 700; font-size: 16px; text-transform: uppercase; letter-spacing: .04em; margin-bottom: 8px; }
.cube-field label .req { color: var(--cube-pink-deep, var(--pink-deep, #f40256)); }
.cube-field input, .cube-field select, .cube-field textarea {
  width: 100%; background: transparent; border: 2px solid #000; color: #000;
  font-family: var(--cube-font-secondary, var(--mono, 'Anonymous Pro', ui-monospace, monospace)); font-size: 15px; padding: 12px 16px; outline: none;
  transition: border-color .2s;
}
.cube-field input:focus, .cube-field textarea:focus { border-color: var(--cube-pink, var(--pink, #f70087)); }
.cube-field.full { grid-column: 1 / -1; }

/* ---------- Quote ---------- */
.cube-quote {
  position: relative; padding: 48px 96px; font: 700 28px/1.35 var(--cube-font-primary, var(--font, 'Poppins', system-ui, sans-serif));
  text-align: center; max-width: 920px; margin: 0 auto;
}
.cube-quote::before, .cube-quote::after {
  content: ""; position: absolute; width: 64px; height: 50px;
  background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 50' fill='%23f70087'><path d='M0 50V28C0 12 10 2 28 0l3 10c-10 3-15 8-15 16h12v24zm32 0V28c0-16 10-26 28-28l3 10c-10 3-15 8-15 16h12v24z'/></svg>") center/contain no-repeat;
}
.cube-quote::before { top: -4px; left: 0; }
.cube-quote::after  { bottom: -4px; right: 0; transform: rotate(180deg); }
.cube-quote cite { display: block; font: 400 14px/1.5 var(--cube-font-secondary, var(--mono, 'Anonymous Pro', ui-monospace, monospace)); color: var(--cube-gray-500, var(--gray-500, #5b5b5b)); margin-top: 20px; font-style: normal; }

/* ---------- Stat ---------- */
.stat { border: 3px solid #000; background: #fff; box-shadow: var(--cube-shadow-sm, var(--shadow-sm, 4px 4px 0 0 #000)); padding: 24px 20px 20px; }
.stat .n { font: italic 800 72px/0.95 var(--cube-font-primary, var(--font, 'Poppins', system-ui, sans-serif)); color: #000; }
.stat .n .pink { color: var(--cube-pink, var(--pink, #f70087)); }
.stat .l { font: 400 14px/1.4 var(--cube-font-secondary, var(--mono, 'Anonymous Pro', ui-monospace, monospace)); color: var(--cube-gray-500, var(--gray-500, #5b5b5b)); text-transform: uppercase; letter-spacing: .08em; margin-top: 10px; }

/* ---------- Icon helper ---------- */
.cube-icon { width: 1em; height: 1em; object-fit: contain; display: inline-block; vertical-align: middle; }

/* ---------- Animated stripe / marquee ----------
   A tilted white strip whose row scrolls infinitely (pauses on hover). Duplicate
   the item set inside .kos-stripe-track so the -50% loop is seamless. Tune with
   --stripe-speed (default 38s) and --stripe-tilt (default -2deg; set 0deg for a
   flat strip). The strip bleeds a little wider than its box to hide the tilted
   corners — place it inside an overflow-hidden wrapper. */
.kos-stripe {
  position: relative; width: 112%; margin-left: -6%;
  background: #fff; border-top: 4px solid #000; border-bottom: 4px solid #000;
  transform: rotate(var(--stripe-tilt, -2deg));
}
.kos-stripe-viewport {
  overflow: hidden; padding: 22px 0;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.kos-stripe-track {
  display: flex; align-items: center; gap: clamp(48px, 6vw, 100px); width: max-content;
  animation: kos-stripe-marquee var(--stripe-speed, 38s) linear infinite;
}
.kos-stripe:hover .kos-stripe-track { animation-play-state: paused; }
.kos-stripe-item {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 12px; white-space: nowrap;
  font: 800 clamp(18px, 1.5vw, 22px) var(--cube-font-primary, var(--font, 'Poppins', system-ui, sans-serif)); color: #0a0a0a;
}
.kos-stripe-item svg, .kos-stripe-item img { width: 26px; height: 26px; flex: 0 0 auto; }
@keyframes kos-stripe-marquee { to { transform: translateX(-50%); } }


/* ============================================================
   .cube-highlight — ported from the 3SC website's Highlight element
   (3sidedcube/3sc-website · src/components/elements/Highlight/Highlight.tsx)

   Theirs is React + Tailwind + Framer Motion:
     <span class="relative z-10 bg-transparent px-1">
       <m.span initial={{width:0}} animate={{width:"100%"}}
               transition={{delay:1, duration:.3, mass:.5, stiffness:120, damping:4}}
               class="absolute inset-0 -z-10" style={{backgroundColor: COLORS.secondary.yellow}} />
       <span class="relative z-10">{children}</span>
     </span>

   The valuable part isn't the yellow, it's that the highlight WIPES IN behind
   the words rather than just being there. Straight port:
     · the Tailwind utilities become six declarations
     · the motion span becomes a ::before whose width transitions 0 -> 100%
     · their spring (damping 4, so it overshoots) becomes --ease-bounce
     · the colour is their token, COLORS.secondary.yellow = #FFD100

   Add .is-lit to the element (or any ancestor) to play it.
   ============================================================ */
.cube-highlight {
  position: relative; z-index: 0;
  padding: 0 .25em;                        /* their px-1, in text-relative units */
  background: transparent;
  box-decoration-break: clone; -webkit-box-decoration-break: clone;
}
.cube-highlight::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  width: 0;
  background: var(--cube-yellow, var(--yellow, #FFD100));
  transition: width .3s var(--ease-bounce, cubic-bezier(0.34, 1.56, 0.64, 1));
}
.cube-highlight.is-lit::before,
.is-lit .cube-highlight::before,
.is-in .cube-highlight::before,
/* ProcessCard lights its title highlight off the same in-view signal —
   theirs is <RoughNotation show={isInView} animationDelay={800}> */
.cube-process.is-inview .cube-highlight::before { width: 100%; }
.cube-process .cube-highlight::before { transition-delay: .8s; }
/* when cube-kit.js has attached the real rough-notation marker, drop the clean CSS
   bar so only the rough one shows (falls back to the clean bar if the lib is absent) */
.cube-highlight.rough-on::before { display: none; }
/* no motion: it's simply already there */

