/**
 * DEKA base layer
 *
 * Reset, document defaults and the heading scale. Everything here is element-level;
 * component styles live in their own files under components/.
 */

/* ==========================================================================
   Reset
   ========================================================================== */

*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  margin: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  tab-size: 4;
}

/* Lenis drives scrolling; native smooth scroll would fight it. */
html:not(.lenis) {
  scroll-behavior: smooth;
}

html.lenis,
html.lenis body {
  height: auto;
}

.lenis.lenis-smooth {
  scroll-behavior: auto !important;
}

.lenis.lenis-stopped {
  overflow: hidden;
}

body {
  min-height: 100vh;
  background-color: var(--deka-surface-page);
  color: var(--deka-text);
  font-family: var(--deka-font-body);
  font-size: var(--deka-text-base);
  line-height: var(--deka-leading-normal);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

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

/* The rule above is an author rule, so it beats the user agent's
   `[hidden] { display: none }` no matter how specific that is — which means
   the hidden attribute silently does nothing on every image, video and svg in
   the theme. This restores it. */
[hidden] {
  display: none !important;
}

input,
button,
textarea,
select {
  font: inherit;
  color: inherit;
}

button {
  -webkit-tap-highlight-color: transparent;
  cursor: pointer;
  background: none;
  border: 0;
  padding: 0;
}

p,
h1,
h2,
h3,
h4,
h5,
h6 {
  overflow-wrap: break-word;
}

ul[role='list'],
ol[role='list'] {
  list-style: none;
  padding: 0;
}

/* ==========================================================================
   Typography scale
   ==========================================================================
   Heading LEVEL carries document structure; heading SIZE is presentational.
   Components accept a heading level and may pair it with any .deka-h-* class,
   so hierarchy stays correct wherever a component is placed.
   ========================================================================== */

h1,
h2,
h3,
h4,
h5,
h6 {
  font-family: var(--deka-font-display);
  font-weight: var(--deka-weight-bold);
  line-height: var(--deka-leading-tight);
  letter-spacing: var(--deka-tracking-tight);
  text-wrap: balance;
}

h1,
.deka-h-1 {
  font-size: var(--deka-text-3xl);
}

h2,
.deka-h-2 {
  font-size: var(--deka-text-2xl);
}

h3,
.deka-h-3 {
  font-size: var(--deka-text-xl);
}

h4,
.deka-h-4 {
  font-size: var(--deka-text-lg);
}

h5,
.deka-h-5 {
  font-size: var(--deka-text-md);
}

h6,
.deka-h-6 {
  font-size: var(--deka-text-base);
  letter-spacing: var(--deka-tracking-wide);
  text-transform: uppercase;
}

p {
  text-wrap: pretty;
}

a {
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
  transition: color var(--deka-duration-fast) var(--deka-ease-out);
}

a:hover {
  color: var(--deka-action-hover);
}

strong,
b {
  font-weight: var(--deka-weight-semibold);
}

/* Eyebrow / label text above headings. */
.deka-eyebrow {
  font-family: var(--deka-font-display);
  font-size: var(--deka-text-sm);
  font-weight: var(--deka-weight-medium);
  letter-spacing: var(--deka-tracking-wider);
  text-transform: uppercase;
  color: var(--deka-text-brand);
}

.deka-lead {
  font-size: var(--deka-text-md);
  line-height: var(--deka-leading-relaxed);
  color: var(--deka-text-muted);
}

/* ==========================================================================
   Layout primitives
   ========================================================================== */

.deka-container {
  width: 100%;
  max-width: var(--deka-container-max);
  margin-inline: auto;
  padding-inline: var(--deka-gutter);
}

.deka-container--narrow {
  max-width: var(--deka-container-narrow);
}

.deka-section {
  padding-block: var(--deka-section-gap);
}

.deka-stack > * + * {
  margin-block-start: var(--deka-space-sm);
}

.deka-stack--lg > * + * {
  margin-block-start: var(--deka-space-lg);
}

/* ==========================================================================
   Accessibility
   ========================================================================== */

:where(a, button, input, textarea, select, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--deka-focus-ring);
  outline-offset: 3px;
  border-radius: 2px;
}

.deka-visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.deka-skip-link {
  position: absolute;
  top: var(--deka-space-2xs);
  left: var(--deka-space-2xs);
  z-index: var(--deka-z-toast);
  padding: var(--deka-space-2xs) var(--deka-space-sm);
  background: var(--deka-surface-raised);
  color: var(--deka-text-brand);
  border-radius: var(--deka-radius-sm);
  box-shadow: var(--deka-shadow-md);
  transform: translateY(-200%);
  transition: transform var(--deka-duration-fast) var(--deka-ease-out);
}

.deka-skip-link:focus {
  transform: translateY(0);
}

/* ==========================================================================
   Scroll reveal — see assets/js/motion.js
   ==========================================================================
   Elements only start hidden when JS is present, so a failed script or a
   crawler never leaves content invisible.
   ========================================================================== */

.deka-js [data-deka-reveal] {
  opacity: 0;
  will-change: transform, opacity;
}

.deka-js [data-deka-reveal='fade-up'] {
  transform: translateY(var(--deka-reveal-distance));
}

.deka-js [data-deka-reveal='fade-in'] {
  transform: none;
}

.deka-js [data-deka-reveal].is-revealed {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .deka-js [data-deka-reveal] {
    opacity: 1;
    transform: none;
  }
}

/* ==========================================================================
   Split headings — see splitText() in assets/js/motion.js
   ==========================================================================
   Characters slide up from behind a per-word mask. The heading only hides
   while JS is present and un-split, so no-JS visitors and crawlers always get
   the text, and it can never be left invisible if the script fails.
   ========================================================================== */

.deka-js [data-deka-split]:not(.is-split) {
  visibility: hidden;
  /* Safety net: reveal even if the script never runs. */
  animation: deka-split-fallback 0s 1.2s forwards;
}

@keyframes deka-split-fallback {
  to {
    visibility: visible;
  }
}

[data-deka-split].is-split {
  visibility: visible;
}

.deka-split__word {
  display: inline-block;
  overflow: hidden;
  /* Descenders would otherwise be clipped by the mask. */
  padding-block-end: 0.12em;
  margin-block-end: -0.12em;
  vertical-align: top;
}

.deka-split__char {
  display: inline-block;
  will-change: transform;
}

/* The words variant fades rather than sliding, so it needs no mask — and the
   mask's overflow would clip descenders across a multi-line paragraph. */
[data-deka-split].is-words .deka-split__word {
  overflow: visible;
  padding-block-end: 0;
  margin-block-end: 0;
  vertical-align: baseline;
  will-change: opacity;
}

@media (prefers-reduced-motion: reduce) {
  .deka-js [data-deka-split]:not(.is-split) {
    visibility: visible;
    animation: none;
  }
}

/* ==========================================================================
   Page sections (project pages)
   ==========================================================================
   One frame and one heading for every section, so the sections read as one
   page: the header's 1800 width and side padding, one vertical rhythm, and a
   heading of an optional label over a 32px title with its first word bold,
   with an optional link at the far end of the row. On project pages the
   rhythm is tightened and collapsed to one gap per seam (end of this block). */

.deka-section {
  max-width: 112.5rem; /* 1800 — the header's width */
  margin-inline: auto;
  padding: var(--deka-section-gap) var(--deka-space-lg);
}

.deka-section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem 2rem;
  margin-bottom: clamp(1.75rem, 1rem + 2vw, 3rem);
}

.deka-section-head__eyebrow {
  display: block;
  margin-bottom: 0.75rem;
  font-size: 0.75rem;
  font-weight: var(--deka-weight-medium);
  color: var(--deka-text-muted);
}

.deka-section-head__title {
  margin: 0;
  font-family: var(--deka-font-display);
  font-size: clamp(1.5rem, 1.1rem + 1.2vw, 2rem); /* 24 → 32 */
  font-weight: var(--deka-weight-medium);
  line-height: 1.15;
  color: inherit;
}

.deka-section-head__title strong { font-weight: var(--deka-weight-bold); }

.deka-section-head__lead {
  max-width: 42rem;
  margin: 0.875rem 0 0;
  font-size: 1rem;
  line-height: 1.6;
  color: var(--deka-text-muted);
}

.deka-section-head__action {
  font-size: var(--deka-text-sm);
  font-weight: var(--deka-weight-semibold);
  color: inherit;
  text-decoration: none;
  white-space: nowrap;
}

.deka-section-head__action::after { content: '\00a0\2192'; }
/* Colour restated: the global a:hover above would otherwise fade the label to
   grey as the underline (its intended hover) appears. */
.deka-section-head__action:hover { color: inherit; text-decoration: underline; text-underline-offset: 3px; }

@media (max-width: 40rem) {
  .deka-section { padding-inline: 1.25rem; }
}

/* --- Project pages: one gap at every seam ----------------------------------
   The light sections of a project page — about, apartments, gallery, FAQ, map
   — follow one another on the same ground, so each one's own top and bottom
   padding added up to a double gap at every seam (208px at 1440). Here:
   - the gap is a little tighter than elsewhere: 48 → 96 rather than 48 → 120;
   - a light section that follows another drops its top padding, since the
     one above already supplies the gap;
   - the FAQ (not a .deka-section) and the closing band's light lead-in take
     the same gap, so every seam on the page is one and the same measure.
   The bands — the facts bar, the dark benefits band, the photo of the closing
   band — keep their own padding, and a light section after one of them starts
   with the full gap. Any section may be missing (sold-out projects skip the
   apartments and the FAQ); sibling selectors hold for every combination as
   long as the sections stay direct siblings in <main>. body.single-project
   puts these over the components' own single-class rules in any file order. */

body.single-project {
  --deka-section-gap: clamp(3rem, 1.5rem + 4vw, 6rem); /* 48 → 96 */
}

body.single-project .deka-apartment-faq {
  padding-top: var(--deka-section-gap);
  padding-bottom: var(--deka-section-gap);
}

body.single-project .deka-project-cta {
  padding-top: var(--deka-section-gap);
}

/* The gallery keeps its frame and padding on an inner .deka-section. */
body.single-project :is(.deka-project-intro, .deka-project-apartments, .deka-project-gallery, .deka-apartment-faq, .deka-project-map)
  + :is(.deka-project-intro, .deka-project-apartments, .deka-project-gallery, .deka-apartment-faq, .deka-project-map, .deka-project-cta),
body.single-project :is(.deka-project-intro, .deka-project-apartments, .deka-project-gallery, .deka-apartment-faq, .deka-project-map)
  + .deka-project-gallery > .deka-section {
  padding-top: 0;
}
