/* Components. */

/* ---------------------------------------------------------------------------
   Buttons.

   Three tiers, and only one of them is rose. Sheena's weakness is that it has
   no CTA colour at all, so its Add to Cart is out-ranked by its own quantity
   stepper. Here the buy action is the single saturated element on any page.

   The shape is the signature: a true square trim with a hairline rule set 5px
   inside it. That inset frame is how apothecary labels, perfume cartons and
   engraved specimen plates are set — the rule sits inside the trim edge rather
   than on it. A 2px radius reads as a default app button and a full pill is the
   beauty-theme cliché; this is neither, and it repeats the same hairline
   language as the formulation rail and the product plate.
--------------------------------------------------------------------------- */
.k-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--k-space-2);
  min-height: 54px;
  padding: 1rem 2.5rem;
  border-radius: 0;
  font-family: var(--k-font-body);
  font-size: var(--k-size-small);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--k-duration) var(--k-ease),
              color var(--k-duration) var(--k-ease),
              border-color var(--k-duration) var(--k-ease);
}

/* The inset rule. Decorative only, so it carries no contrast requirement. */
.k-btn::after {
  content: "";
  position: absolute;
  inset: 5px;
  border: 1px solid currentColor;
  opacity: 0.32;
  pointer-events: none;
  transition: inset var(--k-duration) var(--k-ease), opacity var(--k-duration) var(--k-ease);
}

/* On hover the frame draws in a fraction — a considered movement rather than a
   bounce or a glow. */
.k-btn:hover::after,
.k-btn:focus-visible::after {
  inset: 3px;
  opacity: 0.5;
}

/* Tier 1 — the buy action. Rose, and nothing else on the page is rose. */
.k-btn--buy {
  background-color: var(--k-rose);
  color: var(--k-surface);
  border: 1px solid var(--k-rose);
  min-height: 58px;
}
.k-btn--buy:hover,
.k-btn--buy:focus-visible {
  background-color: var(--k-rose-deep);
  border-color: var(--k-rose-deep);
  color: var(--k-surface);
}

/* rose on forest measures 2.22:1 and is a forbidden pair. A buy button inside
   a forest panel must sit on its own light surface, which this enforces. */
.k-on-forest .k-btn--buy {
  outline: 3px solid var(--k-paper);
  outline-offset: 0;
}

/* Tier 2 — secondary. The trim rule and the inset rule together read as an
   engraved plate; brass carries the inner line because it is ornament here,
   never text. */
.k-btn--secondary {
  background-color: transparent;
  color: var(--k-ink);
  border: 1px solid var(--k-rule-strong);
}
.k-btn--secondary::after {
  border-color: var(--k-brass);
  opacity: 0.55;
}
.k-btn--secondary:hover,
.k-btn--secondary:focus-visible {
  border-color: var(--k-ink);
  background-color: var(--k-surface);
  color: var(--k-ink);
}
.k-btn--secondary:hover::after { opacity: 0.85; }
.k-on-forest .k-btn--secondary {
  color: var(--k-paper);
  border-color: color-mix(in srgb, var(--k-paper) 40%, transparent);
}
.k-on-forest .k-btn--secondary:hover { border-color: var(--k-paper); }

/* Tier 3 — quiet. A single rule under the text; no frame, so the device stays
   reserved for the two tiers that are actually buttons. */
.k-btn--quiet {
  min-height: 48px;
  padding-inline: 0;
  background: none;
  color: var(--k-ink);
  border-bottom: 1px solid var(--k-rule-strong);
  border-radius: 0;
}
.k-btn--quiet::after { content: none; }
.k-btn--quiet:hover { border-bottom-color: var(--k-ink); }

.k-btn[disabled],
.k-btn[aria-disabled="true"] {
  opacity: 0.45;
  cursor: not-allowed;
}

/* ---------------------------------------------------------------------------
   The formulation rail — the signature element.

   Kihara's real story is a chemist formulating botanical oils in Kingston, so
   product surfaces carry a specimen-plate metadata rail: small-caps labels over
   display-face values, divided by hairlines. It is typographic rather than
   decorative, and it encodes true information (volume, actives, origin) rather
   than ornament.
--------------------------------------------------------------------------- */
.k-rail {
  display: flex;
  flex-wrap: wrap;
  border-top: 1px solid var(--k-rule);
  border-bottom: 1px solid var(--k-rule);
  margin-block: var(--k-space-5);
}

.k-rail__item {
  flex: 1 1 auto;
  min-width: 8rem;
  padding: var(--k-space-3) var(--k-space-4) var(--k-space-3) 0;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.k-rail__item + .k-rail__item {
  padding-left: var(--k-space-4);
  border-left: 1px solid var(--k-rule);
}

.k-rail__label {
  font-size: var(--k-size-meta);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--k-tracking-wide);
  color: var(--k-ink-muted);
}

.k-rail__value {
  font-family: var(--k-font-display);
  font-size: var(--k-size-h3);
  line-height: 1.2;
  color: var(--k-ink);
}

/* 40%, not 22%: these dividers separate data in the rail, so they are
   structural rather than decorative and are held to the 3:1 non-text
   minimum. Composited over forest this measures 3.31:1. */
.k-on-forest .k-rail { border-color: color-mix(in srgb, var(--k-paper) 40%, transparent); }
.k-on-forest .k-rail__item + .k-rail__item { border-left-color: color-mix(in srgb, var(--k-paper) 40%, transparent); }
.k-on-forest .k-rail__label { color: var(--k-brass-on-forest); }
.k-on-forest .k-rail__value { color: var(--k-paper); }

@media (max-width: 34rem) {
  .k-rail__item { flex-basis: 100%; }
  .k-rail__item + .k-rail__item {
    padding-left: 0;
    border-left: 0;
    border-top: 1px solid var(--k-rule);
  }
}

/* ---------------------------------------------------------------------------
   Product card. No border, no shadow, no panel — the image sits on the ground
   and typography does the separating. Elevation stacks are the dated tell.
--------------------------------------------------------------------------- */
.k-card {
  display: flex;
  flex-direction: column;
  gap: var(--k-space-2);
  position: relative;
  background: none;
  border: 0;
  box-shadow: none;
}

/*
 * The product plate.
 *
 * Not plain white. Two warm tones meeting at a hard edge read as a studio
 * backdrop with the bottle standing on a plinth — a real photographic
 * convention rather than a decorative wash, and warmer and more considered than
 * a clinical white box. The hairline frame is the same device as the button,
 * set inside the trim edge the way a specimen plate is ruled.
 */
.k-card__media {
  position: relative;
  display: block;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  margin-bottom: var(--k-space-3);
  background: none;
}

/* The plate itself. Inset to exactly the same box as the frame so the plinth
   band is contained by the rule instead of bleeding past it. */
.k-card__media::before {
  content: "";
  position: absolute;
  inset: 10px;
  background-image: linear-gradient(
    to bottom,
    var(--k-paper) 0%,
    var(--k-paper) 74%,
    var(--k-paper-sunk) 74%,
    var(--k-paper-sunk) 100%
  );
  transition: inset var(--k-duration) var(--k-ease);
}

.k-card__media::after {
  content: "";
  position: absolute;
  inset: 10px;
  border: 1px solid var(--k-rule);
  pointer-events: none;
  transition: inset var(--k-duration) var(--k-ease);
}

.k-card__media img { position: relative; z-index: 1; }

/* Product photography is 2014-era and caps near 623px wide, so it is displayed
   small enough to stay close to 2x rather than blown up and soft. */
.k-card__media img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: clamp(1.25rem, 4%, 2.25rem);
  transition: transform var(--k-duration) var(--k-ease);
}

/* The bottle lifts off the plinth rather than scaling. A rise reads as a
   physical object; a scale reads as a zoom. */
.k-card:hover .k-card__media img { transform: translateY(-6px); }
.k-card:hover .k-card__media::after,
.k-card:hover .k-card__media::before { inset: 7px; }

.k-card__title {
  font-family: var(--k-font-display);
  font-size: var(--k-size-h3);
  line-height: 1.25;
  color: var(--k-ink);
}

.k-card__title a { text-decoration: none; }
.k-card__title a:hover { text-decoration: underline; }

/* Stretch the title link over the whole card so the hit area is the card. */
.k-card__title a::after {
  content: "";
  position: absolute;
  inset: 0;
}

.k-card__meta {
  font-size: var(--k-size-meta);
  text-transform: uppercase;
  letter-spacing: var(--k-tracking-wide);
  color: var(--k-ink-muted);
}

/* ---------------------------------------------------------------------------
   Price. 15 of 23 products are on sale, so sale is the normal state, not an
   accent. A struck regular price in muted ink — no red, no ribbon, no badge.
   A loud sale treatment would make the site read as clearance.
--------------------------------------------------------------------------- */
.k-price {
  font-family: var(--k-font-body);
  font-size: var(--k-size-body);
  font-weight: 600;
  color: var(--k-ink);
  font-variant-numeric: tabular-nums;
}

.k-price del {
  font-weight: 400;
  color: var(--k-ink-muted);
  text-decoration-thickness: 1px;
  margin-right: var(--k-space-2);
}

.k-price ins { text-decoration: none; }

.k-price--large { font-size: var(--k-size-lead); }

/* ---------------------------------------------------------------------------
   Page banner and breadcrumb. One standard header for every inner template.
--------------------------------------------------------------------------- */
.k-banner {
  padding-block: var(--k-space-7) var(--k-space-6);
  border-bottom: 1px solid var(--k-rule);
}

/*
 * The banner subtitle is auto-generated from page content when no excerpt is
 * set, so it carries whatever the page happens to contain — including bare URLs
 * and, on legacy pages, raw shortcode text from a previous theme. Those are
 * unbreakable strings that pushed the document to 433px inside a 320px viewport.
 *
 * The article body already has this safety net; the banner did not, which is why
 * the overflow survived. Fixing the content is the real answer, but no page
 * should be able to break the layout by existing.
 */
.k-banner h1,
.k-banner p {
  overflow-wrap: anywhere;
}


.k-banner__inner {
  display: flex;
  flex-direction: column;
  gap: var(--k-space-3);
  max-width: var(--k-measure);
}

.k-breadcrumb {
  font-size: var(--k-size-meta);
  text-transform: uppercase;
  letter-spacing: var(--k-tracking-wide);
  color: var(--k-ink-muted);
}

.k-breadcrumb ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  list-style: none;
  padding: 0;
  margin: 0;
}

.k-breadcrumb li { display: inline-flex; align-items: center; }

.k-breadcrumb li + li::before {
  content: "/";
  margin-right: 0.5rem;
  color: var(--k-rule-strong);
}

.k-breadcrumb a {
  display: inline-flex;
  align-items: center;
  min-height: 48px;
  text-decoration: none;
  color: var(--k-ink-muted);
}
.k-breadcrumb a:hover { color: var(--k-ink); text-decoration: underline; }

/* ---------------------------------------------------------------------------
   Quantity stepper. Deliberately subordinate to the buy button: bare, ruled,
   ink-coloured, never saturated.
--------------------------------------------------------------------------- */
.k-qty {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--k-rule-strong);
  border-radius: var(--k-radius);
  background-color: var(--k-surface);
  overflow: hidden;
}

.k-qty button {
  width: 48px;
  min-height: 52px;
  color: var(--k-ink);
  font-size: var(--k-size-body);
  line-height: 1;
}

.k-qty button:hover { background-color: var(--k-paper-sunk); }

.k-qty input {
  width: 3.25rem;
  min-height: 52px;
  border: 0;
  border-inline: 1px solid var(--k-rule);
  text-align: center;
  font-variant-numeric: tabular-nums;
  background: none;
  -moz-appearance: textfield;
}

.k-qty input::-webkit-outer-spin-button,
.k-qty input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* ---------------------------------------------------------------------------
   Notices.
--------------------------------------------------------------------------- */
.k-notice {
  padding: var(--k-space-3) var(--k-space-4);
  border-left: 2px solid var(--k-forest);
  background-color: var(--k-forest-tint);
  color: var(--k-ink);
  font-size: var(--k-size-small);
}

/* ---------------------------------------------------------------------------
   Search form.
--------------------------------------------------------------------------- */
.k-search-form {
  display: flex;
  gap: var(--k-space-2);
  align-items: stretch;
  max-width: 30rem;
}

.k-search-form__input {
  flex: 1 1 auto;
  min-height: 52px;
  padding: 0 var(--k-space-3);
  border: 1px solid var(--k-rule-strong);
  border-radius: 0;
  background-color: var(--k-surface);
  color: var(--k-ink);
  font-size: var(--k-size-body);
}

.k-search-form__input::placeholder { color: var(--k-ink-muted); opacity: 1; }
.k-search-form__input:focus-visible { outline-offset: 1px; }
