/* Kubu Gajah luxury DaisyUI theme */
[data-theme="kubugajah"] {
  color-scheme: light;

  --p: 48.00% 0.035 75;          /* primary: #776c4a (luxury gold) */
  --pc: 100% 0 0;                /* primary-content: #FFFFFF */

  --s: 22.00% 0.005 0;           /* secondary: #1a1a1a (dark) */
  --sc: 100% 0 0;                /* secondary-content: #FFFFFF */

  --a: 72.00% 0.070 85;          /* accent: #C6A96A (champagne gold) */
  --ac: 17.00% 0 0;              /* accent-content: #111111 */

  --n: 20.00% 0 0;               /* neutral: #1F1F1F */
  --nc: 100% 0 0;                /* neutral-content: #FFFFFF */

  --b1: 100% 0 0;                /* base-100: #FFFFFF */
  --b2: 98.50% 0.001 250;        /* base-200: #f8f9fa (neutral light) */
  --b3: 93.00% 0.003 250;        /* base-300: #e9ecef (neutral gray) */
  --bc: 17.00% 0 0;              /* base-content: #111111 */

  --in: 55.00% 0.040 250;        /* info: #6B7F99 (slate blue) */
  --inc: 100% 0 0;
  --su: 58.00% 0.045 145;        /* success: #7A8F6E (muted sage) */
  --suc: 100% 0 0;
  --wa: 70.00% 0.065 85;         /* warning: #B8A06A (warm gold) */
  --wac: 17.00% 0 0;
  --er: 48.00% 0.070 10;         /* error: #9B5563 (muted wine) */
  --erc: 100% 0 0;

  --rounded-box: 0.375rem;
  --rounded-btn: 0.25rem;
  --rounded-badge: 0.25rem;
  --animation-btn: 0.2s;
  --animation-input: 0.2s;
  --btn-focus-scale: 0.98;
  --border-btn: 1px;
  --tab-border: 1px;
  --tab-radius: 0;
}

/* Luxury typography — the faces are vendored in /css/fonts.css and linked from
   layout/public.html. They used to be an @import right here, which the browser discarded:
   CSS requires @import to precede every style rule and this file opens with one on line 2.
   Do not reintroduce it; add families to tools/google-fonts-vendor.py instead. */

[data-theme="kubugajah"] {
  font-family: 'Inter', 'Helvetica Neue', sans-serif;
}

[data-theme="kubugajah"] h1,
[data-theme="kubugajah"] h3 {
  font-family: 'Cormorant Garamond', serif;
  font-weight: 600;
  letter-spacing: 0.02em;
}

[data-theme="kubugajah"] h2 {
  font-family: 'Cinzel', 'Playfair Display', serif;
  font-weight: 400;
  letter-spacing: 0.08em;
}

/* Luxury button overrides */
[data-theme="kubugajah"] .btn {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 500;
  font-size: 0.8rem;
}

/* Ghost button */
[data-theme="kubugajah"] .btn-ghost {
  border: 1px solid rgba(119, 108, 74, 0.12);
  color: #776c4a;
}
[data-theme="kubugajah"] .btn-ghost:hover {
  border-color: rgba(119, 108, 74, 0.3);
  background-color: rgba(119, 108, 74, 0.05);
}

/* Semantic buttons default to outline */
[data-theme="kubugajah"] .btn-secondary:not(.btn-outline) {
  background-color: transparent;
  color: oklch(var(--s));
  border: 1px solid oklch(var(--s));
}
[data-theme="kubugajah"] .btn-secondary:not(.btn-outline):hover {
  background-color: oklch(var(--s));
  color: oklch(var(--sc));
}
[data-theme="kubugajah"] .btn-info:not(.btn-outline) {
  background-color: transparent;
  color: oklch(var(--in));
  border: 1px solid oklch(var(--in));
}
[data-theme="kubugajah"] .btn-info:not(.btn-outline):hover {
  background-color: oklch(var(--in));
  color: oklch(var(--inc));
}
[data-theme="kubugajah"] .btn-success:not(.btn-outline) {
  background-color: transparent;
  color: oklch(var(--su));
  border: 1px solid oklch(var(--su));
}
[data-theme="kubugajah"] .btn-success:not(.btn-outline):hover {
  background-color: oklch(var(--su));
  color: oklch(var(--suc));
}
[data-theme="kubugajah"] .btn-warning:not(.btn-outline) {
  background-color: transparent;
  color: oklch(var(--wa));
  border: 1px solid oklch(var(--wa));
}
[data-theme="kubugajah"] .btn-warning:not(.btn-outline):hover {
  background-color: oklch(var(--wa));
  color: oklch(var(--wac));
}
[data-theme="kubugajah"] .btn-error:not(.btn-outline) {
  background-color: transparent;
  color: oklch(var(--er));
  border: 1px solid oklch(var(--er));
}
[data-theme="kubugajah"] .btn-error:not(.btn-outline):hover {
  background-color: oklch(var(--er));
  color: oklch(var(--erc));
}
[data-theme="kubugajah"] .btn-accent:not(.btn-outline) {
  background-color: transparent;
  color: oklch(var(--a));
  border: 1px solid oklch(var(--a));
}
[data-theme="kubugajah"] .btn-accent:not(.btn-outline):hover {
  background-color: oklch(var(--a));
  color: oklch(var(--ac));
}

/* Soft tint badges */
[data-theme="kubugajah"] .badge-info:not(.badge-outline) {
  background-color: rgba(107, 127, 153, 0.10);
  color: #5A6E85;
  border: none;
}
[data-theme="kubugajah"] .badge-success:not(.badge-outline) {
  background-color: rgba(122, 143, 110, 0.10);
  color: #5F7353;
  border: none;
}
[data-theme="kubugajah"] .badge-warning:not(.badge-outline) {
  background-color: rgba(184, 160, 106, 0.12);
  color: #8C7A4A;
  border: none;
}
[data-theme="kubugajah"] .badge-error:not(.badge-outline) {
  background-color: rgba(155, 85, 99, 0.10);
  color: #8B4A5E;
  border: none;
}
[data-theme="kubugajah"] .badge-ghost {
  background-color: rgba(0, 0, 0, 0.05);
  color: #888888;
  border: none;
}

/* Outline alerts */
[data-theme="kubugajah"] .alert-info {
  background-color: rgba(107, 127, 153, 0.06);
  color: #5A6E85;
  border: 1px solid rgba(107, 127, 153, 0.25);
}
[data-theme="kubugajah"] .alert-success {
  background-color: rgba(122, 143, 110, 0.06);
  color: #5F7353;
  border: 1px solid rgba(122, 143, 110, 0.25);
}
[data-theme="kubugajah"] .alert-warning {
  background-color: rgba(184, 160, 106, 0.06);
  color: #8C7A4A;
  border: 1px solid rgba(184, 160, 106, 0.25);
}
[data-theme="kubugajah"] .alert-error {
  background-color: rgba(155, 85, 99, 0.06);
  color: #8B4A5E;
  border: 1px solid rgba(155, 85, 99, 0.25);
}

/* Toggle */
[data-theme="kubugajah"] .toggle:checked {
  background-color: #776c4a;
  border-color: #776c4a;
}

/* Loading */
[data-theme="kubugajah"] .loading {
  color: oklch(var(--p));
  opacity: 0.6;
}

/* Range slider */
[data-theme="kubugajah"] .range {
  --range-shdw: #776c4a;
}

/* ============================================================ */
/* Navbar — transparent scroll (homepage hero auto-detect)      */
/* ============================================================ */
#daisy-navbar {
  transition: background 0.4s ease-in-out,
              backdrop-filter 0.4s ease-in-out,
              border-color 0.4s ease-in-out;
  background: rgba(0, 0, 0, 0.95);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

/* Transparent over the hero photograph — but not bare (#106, WCAG 1.4.3).
 *
 * The nav links are text-white/80 and the only thing behind them was the hero's own scrim, which
 * is at its weakest exactly here: .hero-slide::after starts at rgba(26,26,26,0.3) and only reaches
 * 0.7 at the bottom of the section. Measured against a near-white photograph — sky, a pool, a
 * whitewashed wall, all of which are in these photographs — that gives **1.72:1** where 4.5:1 is
 * required. It passes only over mid-tone and shadow, so whether the navigation was readable came
 * down to which slide happened to be showing.
 *
 * Raising the hero scrim instead would need 70% to fix it and would flatten the photography, which
 * is the point of the page. A gradient behind the nav alone costs nothing visually: it is dark
 * where the text is and gone by the time the eye reaches the image. 55% at the top measures
 * 5.58:1 on the worst case, against a 47% minimum — the margin is for the photographs we have not
 * taken yet.
 */
#daisy-navbar.transparent-nav {
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0) 100%);
  backdrop-filter: none;
  border-bottom-color: transparent;
}

#daisy-navbar.scrolled {
  background: rgba(0, 0, 0, 0.85);
  backdrop-filter: blur(10px);
  border-bottom-color: rgba(255, 255, 255, 0.1);
}

/* ============================================================ */
/* Hero carousel (homepage)                                     */
/* ============================================================ */
.hero-carousel { position: absolute; inset: 0; }

.hero-slide {
  position: absolute; inset: 0;
  opacity: 0;
  transition: opacity 1.5s ease-in-out;
}
.hero-slide.active { opacity: 1; }
.hero-slide img { width: 100%; height: 100%; object-fit: cover; }
.hero-slide::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(to bottom,
    rgba(26,26,26,0.3) 0%,
    rgba(26,26,26,0.5) 50%,
    rgba(26,26,26,0.7) 100%
  );
}

/* A <button> now, not a <span> (#106), so the browser's own button styling is reset away and
   the 12px dot is drawn as a pseudo-element. The button itself is 24x24 — WCAG 2.5.8 Target Size
   (Minimum), AA in 2.2 — which matters most for the audience this site actually has: older
   travellers, on a phone, in bright sun. The dot stays 12px visually; only the hit area grows. */
.carousel-dot {
  width: 24px; height: 24px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  -webkit-appearance: none;
  appearance: none;
}

.carousel-dot::before {
  content: "";
  display: block;
  width: 12px; height: 12px;
  border-radius: 50%;
  background: rgba(255,255,255,0.4);
  border: 2px solid white;
  transition: all 0.3s;
}

/* Keyboard focus has to be visible on a photograph of any brightness, so it is a ring with its
   own contrast rather than a colour change. */
.carousel-dot:focus-visible {
  outline: 3px solid #fff;
  outline-offset: 3px;
  border-radius: 50%;
}
.carousel-dot.active::before {
  background: white;
  width: 35px;
  border-radius: 6px;
}

/* The pause control sits with the dots rather than over the photograph's focal point. */
.hero-pause {
  position: absolute;
  bottom: 2rem;
  right: 1.5rem;
  pointer-events: auto;
}

.hero-control {
  width: 50px; height: 50px;
  background: rgba(255,255,255,0.1);
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: white;
  cursor: pointer;
  transition: all 0.3s;
}
.hero-control:hover { background: rgba(255,255,255,0.25); transform: scale(1.1); }

/* Smooth scroll */
html { scroll-behavior: smooth; }

/* ============================================================ */
/* Homepage — villa card mini-carousel and hover                */
/* ============================================================ */
.villa-slide {
  position: absolute; inset: 0;
  opacity: 0;
  transition: opacity 0.8s ease-in-out;
}
.villa-slide.active { opacity: 1; }

.villa-card {
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.villa-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 12px 35px rgba(119,108,74,0.15) !important;
}

/* ============================================================ */
/* Villa listing cards                                          */
/* ============================================================ */
.villa-full-card {
  transition: transform 0.3s ease, box-shadow 0.3s ease;
  overflow: hidden;
}
.villa-full-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 10px 30px rgba(119,108,74,0.15) !important;
}
.villa-img { transition: transform 0.3s ease; }
.villa-full-card:hover .villa-img { transform: scale(1.05); }

/* ============================================================ */
/* Gallery — masonry, lightbox, filter tabs                     */
/* ============================================================ */
.masonry { column-count: 3; column-gap: 12px; }
@media (max-width: 1024px) { .masonry { column-count: 2; } }
/* Two columns on phones: at one column, 284 thumbnails made the page 108,926px
   tall (#116). These open a lightbox — they do not need to be full-width. */
@media (max-width: 640px) { .masonry { column-count: 2; } }

.masonry-item {
  break-inside: avoid; margin-bottom: 12px;
  border-radius: 8px; overflow: hidden;
  position: relative; cursor: pointer;
}
.masonry-item img { width: 100%; display: block; transition: transform 0.4s ease; }
.masonry-item:hover img { transform: scale(1.05); }
.masonry-item .overlay {
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(0,0,0,0.6) 0%, transparent 40%);
  opacity: 0; transition: opacity 0.3s ease;
  display: flex; align-items: flex-end; padding: 12px 16px;
}
.masonry-item:hover .overlay { opacity: 1; }
.overlay-text {
  color: white; font-family: 'Cormorant Garamond', serif;
  font-size: 1rem; font-weight: 600; letter-spacing: 0.03em;
}

.gallery-lightbox {
  display: none; position: fixed; inset: 0;
  background: rgba(0,0,0,0.95); z-index: 9999; flex-direction: column;
}
.gallery-lightbox.active { display: flex; }

.lightbox-header {
  display: flex; justify-content: space-between; align-items: center;
  padding: 16px 24px; color: #fff;
}
.lightbox-counter { font-size: 0.95rem; font-weight: 500; }
.lightbox-close {
  background: none; border: none; color: #fff;
  font-size: 1.5rem; cursor: pointer; padding: 4px 8px;
  border-radius: 6px; transition: background 0.2s;
}
.lightbox-close:hover { background: rgba(255,255,255,0.15); }

.lightbox-main {
  flex: 1; display: flex; align-items: center; justify-content: center;
  position: relative; min-height: 0; padding: 0 60px;
}
.lightbox-main img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 4px; }

.lightbox-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  background: rgba(255,255,255,0.15); border: none; color: #fff;
  width: 48px; height: 48px; border-radius: 50%; font-size: 1.3rem;
  cursor: pointer; transition: background 0.2s;
  display: flex; align-items: center; justify-content: center;
}
.lightbox-nav:hover { background: rgba(255,255,255,0.3); }
.lightbox-prev { left: 8px; }
.lightbox-next { right: 8px; }

.lightbox-thumbnails {
  display: flex; gap: 6px; padding: 12px 24px 16px;
  overflow-x: auto; justify-content: center;
  scrollbar-width: thin; scrollbar-color: rgba(255,255,255,0.3) transparent;
}
.lightbox-thumb {
  flex-shrink: 0; width: 64px; height: 48px;
  border-radius: 4px; overflow: hidden; cursor: pointer;
  opacity: 0.5; transition: opacity 0.2s; border: 2px solid transparent;
}
.lightbox-thumb.active { opacity: 1; border-color: #fff; }
.lightbox-thumb:hover { opacity: 0.8; }
.lightbox-thumb img { width: 100%; height: 100%; object-fit: cover; }

@media (max-width: 768px) {
  .lightbox-main { padding: 0 48px; }
  .lightbox-nav { width: 40px; height: 40px; font-size: 1.1rem; }
  .lightbox-thumb { width: 48px; height: 36px; }
}

.filter-tab {
  cursor: pointer; padding: 0.5rem 1.25rem;
  border-radius: 9999px; font-size: 0.8rem; font-weight: 500;
  letter-spacing: 0.05em; text-transform: uppercase;
  /* Named properties, not `all`: `all` includes outline-width, so the focus ring faded in over
     300ms — indistinguishable from having no focus ring at the moment focus arrives, which is
     when a keyboard user needs to see it (#106). A focus indicator must never be animated. */
  transition: color 0.3s ease, background-color 0.3s ease, border-color 0.3s ease;
  border: 1px solid transparent;
  /* 0.6 and not 0.5: black at 50% over white renders #808080, which is 3.94:1 against a 4.5
     floor — the contrast failure Lighthouse found on /gallery (#158). 0.6 gives #666666 at
     5.74:1. Set in a stylesheet rather than a utility class, which is why the template scan
     could not see it. */
  color: rgba(0,0,0,0.6); background: transparent;
}
.filter-tab:hover { color: #776c4a; border-color: rgba(119,108,74,0.3); }
.filter-tab.active { background: #776c4a; color: white; border-color: #776c4a; }

/*
 * Secondary text.
 *
 * A colour, not an opacity — and that is the whole point of the token.
 *
 * This was `opacity: 0.65`, reasoned about as "#111111 blended 65% over white is about #646464,
 * roughly 5.7:1, which passes". Each step of that is true and the conclusion was still wrong,
 * because opacity is not a property of an element: it applies to the whole subtree and it
 * MULTIPLIES through nesting. `.text-soft` inside a `.opacity-70` wrapper renders at 0.455, which
 * axe measured as #929292 — 3.11:1, under the 4.5:1 floor for normal text (#106). The old comment
 * even noted that opacity-60 and opacity-70 "already pass and are left alone", which they do on
 * their own; nothing about them individually predicts what they do together.
 *
 * A descendant cannot undo an ancestor's opacity, so no value of this token could have fixed that.
 * A colour can: it does not compound, it can be checked once, and what you read in the stylesheet
 * is what the pixel is. #595959 on #FFFFFF is 7.0:1, comfortably clear of the floor at the 12–14px
 * sizes this is used at, and still plainly secondary next to #111.
 *
 * A variable so a dark surface can override it in one place — and one does. /reviews puts
 * `.text-soft` inside a filled .btn-primary, where #595959 on the brand brown is 1.06:1: text
 * very nearly invisible. An earlier draft of this comment asserted every current use was on a
 * light background. It was not, and the only reason that is written here rather than shipped is
 * that axe checked it.
 */
[data-theme="kubugajah"] {
  --kg-text-soft: #595959;
}

.text-soft {
  color: var(--kg-text-soft, #595959);
}

/*
 * Muted text on a filled button. Buttons set their own foreground, so the secondary text has to be
 * a tint of that rather than a fixed grey chosen for white.
 */
[data-theme="kubugajah"] .btn-primary .text-soft,
[data-theme="kubugajah"] .btn-secondary .text-soft,
[data-theme="kubugajah"] .btn-neutral .text-soft {
  --kg-text-soft: rgba(255, 255, 255, 0.85);
}

/*
 * DaisyUI's ghost badge is #888888 on #f2f2f2 — 3.16:1, and it carries real content: the bedroom,
 * bathroom and guest counts on /villas, and the venue tags on /location. Same secondary-text
 * colour as everything else, which is 6.2:1 on that background.
 */
[data-theme="kubugajah"] .badge-ghost {
  color: var(--kg-text-soft, #595959);
}

/*
 * Reduced motion (#106).
 *
 * The scripts already stop the two carousels advancing themselves; this covers the transitions
 * that remain — the hero's cross-fade, the villa card's, and the card hover lift — for a guest
 * who has asked their system not to animate. Deliberately not `animation: none`: removing a
 * transition entirely can make a control appear to do nothing, so these collapse to near-instant
 * rather than being cancelled.
 */
@media (prefers-reduced-motion: reduce) {
  [data-theme="kubugajah"] *,
  [data-theme="kubugajah"] *::before,
  [data-theme="kubugajah"] *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/*
 * Focus indicator (WCAG 2.4.7), declared rather than inherited.
 *
 * The theme previously declared no focus styling at all and relied on the browser's default ring.
 * That is fine until something replaces it — the gallery's .filter-tab links draw their own border
 * and the default outline is not visible against it, so tabbing through the gallery filters moved
 * focus with nothing on screen to say where it had gone. A test that only looked at the home page
 * did not see it (#106).
 *
 * :focus-visible rather than :focus, so a mouse click on a button does not leave a ring behind —
 * that is the behaviour that gets focus styling deleted again.
 */
[data-theme="kubugajah"] :focus-visible {
  outline: 2px solid #776c4a;
  outline-offset: 2px;
  /* Belt and braces for the same trap: any component that transitions `all` would otherwise
     animate its focus ring in, and a ring that arrives late is a ring the guest tabs past. */
  transition-property: none;
}

/*
 * On the brand-coloured surfaces the brand outline would disappear into the background, so the
 * ring inverts. Same width and offset, so nothing moves.
 */
[data-theme="kubugajah"] .filter-tab.active:focus-visible,
[data-theme="kubugajah"] .btn-primary:focus-visible,
[data-theme="kubugajah"] .btn-secondary:focus-visible {
  outline-color: #ffffff;
}
