@import 'tailwindcss';
@plugin '@tailwindcss/typography';

/* Third-party base styles, restyled to the design tokens further down. */
@import 'select2/dist/css/select2.css' layer(base);

@source '../../app/**/*.php';
@source '../../resources/views/**/*.blade.php';
@source '../../vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php';
@source '../../storage/framework/views/*.php';

/*
 * ABACO INFRA design tokens — see docs/DESIGN.md.
 *
 * Taken from the brand board and the logo artwork: ABACO orange (#FF9A2E) as the
 * brand mark, charcoal (#333333) as the structural neutral, with a light grey
 * ground. Poppins is the brand typeface.
 *
 * Contrast rule that drives the whole palette: the brand orange scores about
 * 2:1 on white, so it is never used for body links or small text. Orange is a
 * *surface* colour — solid buttons with near-black text, the logo mark, rules
 * and indicators. Interactive text uses `primary-700`, which clears 4.5:1.
 *
 * Never hardcode a hex value in a Blade template.
 */
@theme {
    /* Poppins is the brand typeface; the mono face carries technical metadata. */
    --font-sans: 'Poppins', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif,
        'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
    --font-display: 'Poppins', ui-sans-serif, system-ui, sans-serif;
    --font-mono: 'Fira Code', ui-monospace, 'SFMono-Regular', 'Consolas', monospace;

    /* ── Brand primitives ──────────────────────────────────────────────── */
    --color-primary-50: #fff6ec;
    --color-primary-100: #ffe7cc;
    --color-primary-200: #ffd3a3;
    --color-primary-300: #ffba70;
    --color-primary-400: #ff9a2e;   /* ★ Brand primary, from the brand board */
    --color-primary-500: #f08300;
    --color-primary-600: #cc6d00;
    --color-primary-700: #a35600;   /* Interactive text: 4.6:1 on white */
    --color-primary-800: #7a4000;
    --color-primary-900: #4d2800;
    --color-primary: #ff9a2e;
    --color-primary-light: #ffba70;
    --color-primary-dark: #cc6d00;

    /* Charcoal: the logo's structural mass, and the site's dark register. */
    --color-secondary-50: #f4f4f4;
    --color-secondary-100: #e6e6e6;
    --color-secondary-200: #cccccc;
    --color-secondary-300: #b0b0b0;
    --color-secondary-400: #8c8c8c;   /* Brand board mid grey */
    --color-secondary-500: #666666;
    --color-secondary-600: #4c4c4c;   /* Logo wordmark grey */
    --color-secondary-700: #333333;   /* ★ Brand secondary */
    --color-secondary-800: #232323;
    --color-secondary-900: #141414;
    --color-secondary: #333333;

    /* ── Accent ────────────────────────────────────────────────────────── */
    --color-accent: #a35600;          /* Interactive text and link arrows */
    --color-accent-warm: #fff6ec;     /* Orange-tinted wash */
    --color-accent-off: #f4f4f4;      /* Brand board light grey */

    /* ── Surfaces ──────────────────────────────────────────────────────── */
    --color-background: #f4f4f4;      /* Page ground, from the brand board */
    --color-surface: #ffffff;         /* Cards, panels, modals */
    --color-surface-2: #fafafa;       /* Elevated section */
    --color-surface-muted: #f0f0f0;   /* Alternating sections, inputs */
    --color-surface-tint: #fff6ec;    /* Orange-tinted surface */
    --color-dark: #333333;            /* Footer, navbar, dark bands */
    --color-dark-surface: #262626;
    --color-dark-elevated: #1a1a1a;

    /* ── Text ──────────────────────────────────────────────────────────── */
    --color-text: #1a1a1a;
    --color-text-secondary: #4c4c4c;
    --color-text-muted: #8c8c8c;
    --color-text-hint: #b0b0b0;
    --color-text-brand: #a35600;
    --color-text-inverse: #ffffff;

    /* ── Borders ───────────────────────────────────────────────────────── */
    --color-border-light: #f0f0f0;
    --color-border: #e0e0e0;
    --color-border-strong: #c4c4c4;
    --color-border-brand: #ff9a2e;

    /* ── Semantic ──────────────────────────────────────────────────────── */
    --color-success: #16803c;
    --color-success-light: #dcfce7;
    --color-warning: #b45309;
    --color-warning-light: #fef3c7;
    --color-error: #c2261d;
    --color-error-light: #fee2e2;
    --color-danger: #c2261d;
    --color-info: #0369a1;
    --color-info-light: #e0f2fe;

    /* ── Breakpoints ───────────────────────────────────────────────────── */
    /* Container widths for the wide breakpoints below. */
    --container-8xl: 96rem;     /* 1536px of content at 3xl */
    --container-9xl: 110rem;    /* 1760px of content at 4xl */

    --breakpoint-xs: 22.5rem;   /* 360px */
    --breakpoint-3xl: 120rem;   /* 1920px */
    --breakpoint-4xl: 160rem;   /* 2560px */

    /* ── Fluid type scale ──────────────────────────────────────────────── */
    --text-hero: clamp(2.75rem, 6vw, 5.5rem);
    --text-hero--line-height: 1.02;
    --text-display: clamp(2.25rem, 4vw, 4rem);
    --text-display--line-height: 1.06;
    --text-headline: clamp(1.8rem, 3vw, 3rem);
    --text-headline--line-height: 1.12;
    --text-title: clamp(1.375rem, 1.6vw, 2rem);
    --text-title--line-height: 1.2;

    /* ── Radius ────────────────────────────────────────────────────────── */
    --radius-5xl: 5rem;

    /* ── Elevation. Borders do most of the work; brand shadows are for the
         orange call-to-action surfaces only. ───────────────────────────── */
    --shadow-card: 0 1px 2px rgb(26 26 26 / 0.04), 0 1px 3px rgb(26 26 26 / 0.06);
    --shadow-raised: 0 8px 24px -12px rgb(26 26 26 / 0.28);
    --shadow-brand-sm: 0 2px 8px 0 rgb(255 154 46 / 0.24);
    --shadow-brand-md: 0 4px 16px 0 rgb(255 154 46 / 0.28);
    --shadow-brand-lg: 0 8px 32px 0 rgb(255 154 46 / 0.32);

    /* ── Extra spacing steps ───────────────────────────────────────────── */
    --spacing-128: 32rem;
    --spacing-144: 36rem;
    --spacing-160: 40rem;
    --spacing-200: 50rem;

    /* ── Motion ────────────────────────────────────────────────────────── */
    --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);

    --animate-fade-in: fade-in 0.6s ease-in-out both;
    --animate-slide-up: slide-up 0.6s var(--ease-out-expo) both;
    --animate-shimmer: shimmer 2s linear infinite;
    --animate-pulse-brand: pulse-brand 2s ease-in-out infinite;

    @keyframes fade-in {
        from { opacity: 0; }
        to { opacity: 1; }
    }

    @keyframes slide-up {
        from { opacity: 0; transform: translateY(1.5rem); }
        to { opacity: 1; transform: translateY(0); }
    }

    @keyframes shimmer {
        from { background-position: -200% 0; }
        to { background-position: 200% 0; }
    }

    @keyframes pulse-brand {
        0%, 100% { box-shadow: 0 0 0 0 rgb(255 154 46 / 0.45); }
        50% { box-shadow: 0 0 0 0.5rem rgb(255 154 46 / 0); }
    }
}

/*
 * Brand gradients. Declared as custom properties plus utility classes rather
 * than theme keys, so they can also be referenced directly from a component.
 */
:root {
    --gradient-primary: linear-gradient(135deg, #ff9a2e 0%, #f08300 100%);
    --gradient-primary-deep: linear-gradient(135deg, #cc6d00 0%, #ff9a2e 100%);
    --gradient-brand-fusion: linear-gradient(135deg, #ff9a2e 0%, #333333 100%);
    --gradient-dark: linear-gradient(135deg, #333333 0%, #1a1a1a 100%);
    --gradient-dark-page: linear-gradient(to bottom, #333333, #1a1a1a);
    --gradient-surface: linear-gradient(180deg, #ffffff 0%, #f4f4f4 100%);
    --gradient-warm-fade: linear-gradient(180deg, #fff6ec 0%, #ffffff 100%);
    --gradient-hero-overlay: linear-gradient(to bottom, rgb(26 26 26 / 0.35) 0%, rgb(26 26 26 / 0.88) 100%);
}

@layer base {
    html {
        scroll-behavior: smooth;
        -webkit-text-size-adjust: 100%;
    }

    body {
        @apply bg-background text-text-secondary antialiased;
        font-feature-settings: 'cv11', 'ss01';
    }

    h1, h2, h3, h4, h5, h6 {
        @apply font-display text-text font-semibold tracking-[-0.02em];
        text-wrap: balance;
    }

    p {
        text-wrap: pretty;
    }

    /* Visible focus is an accessibility requirement (SOW B.5), not decoration. */
    :focus-visible {
        @apply outline-2 outline-offset-2 outline-primary-500;
    }

    [x-cloak] {
        display: none !important;
    }

    ::selection {
        @apply bg-primary text-text;
    }

    /*
     * Reduced motion: entrance animations are progressive enhancement, so the
     * final state must be the default. `motion.js` skips its timelines under the
     * same query; this rule covers the CSS-only cases and the pre-hydration flash.
     */
    @media (prefers-reduced-motion: reduce) {
        html {
            scroll-behavior: auto;
        }

        *, *::before, *::after {
            animation-duration: 0.01ms !important;
            animation-iteration-count: 1 !important;
            transition-duration: 0.01ms !important;
            scroll-behavior: auto !important;
        }

        [data-reveal], [data-reveal-child] {
            opacity: 1 !important;
            transform: none !important;
        }
    }
}

/*
 * Buttons and pills are declared as utilities rather than component classes:
 * Tailwind v4 only lets `@apply` reference utilities, and the variants below
 * build on these.
 */
@utility btn {
    @apply inline-flex items-center justify-center gap-2 rounded-lg px-6 py-3 text-sm font-semibold
           transition duration-200 focus-visible:outline-2 focus-visible:outline-offset-2
           disabled:pointer-events-none disabled:opacity-60;
}

@utility card {
    @apply overflow-hidden rounded-xl border border-border bg-surface;
}

@utility pill {
    @apply inline-flex items-center gap-1.5 rounded-full px-3 py-1 text-xs font-medium;
}

@layer components {

    /* ---------- Layout ---------- */

    .container-page {
        @apply mx-auto w-full max-w-7xl px-5 sm:px-8 lg:px-10 3xl:max-w-8xl 4xl:max-w-9xl;
    }

    .container-narrow {
        @apply mx-auto w-full max-w-3xl px-5 sm:px-8 3xl:max-w-4xl;
    }

    .section {
        @apply py-14 sm:py-18 lg:py-22;
    }

    .section-lg {
        @apply py-16 sm:py-22 lg:py-26;
    }

    .section-tight {
        @apply py-10 sm:py-12 lg:py-14;
    }

    .prose-measure {
        @apply max-w-[65ch];
    }

    /* ---------- Typographic roles ---------- */

    /* The orange rule under a label is the brand board's own device. */
    .eyebrow {
        @apply flex items-center gap-2.5 text-[0.6875rem] font-semibold uppercase tracking-[0.22em] text-text-brand;
    }

    .eyebrow::before {
        content: '';
        @apply h-0.5 w-8 bg-primary;
    }

    .eyebrow-plain {
        @apply text-[0.6875rem] font-semibold uppercase tracking-[0.22em] text-text-brand;
    }

    /* Technical metadata: project numbers, coordinates, dimensions. */
    .meta-label {
        @apply font-mono text-[0.6875rem] uppercase tracking-[0.14em] text-text-muted;
    }

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

    .btn-primary {
        @apply btn bg-primary text-text shadow-brand-sm hover:bg-primary-500 hover:shadow-brand-md;
    }

    /* The dark counterpart, for use on orange or light-orange surfaces. */
    .btn-accent {
        @apply btn bg-secondary text-white hover:bg-secondary-800;
    }

    .btn-outline {
        @apply btn border border-border bg-surface text-text hover:border-primary hover:bg-primary-50;
    }

    .btn-ghost {
        @apply btn px-3 text-text-brand hover:bg-primary-50;
    }

    .btn-on-dark {
        @apply btn border border-white/30 text-white hover:border-primary hover:bg-white/10;
    }

    .btn-sm {
        @apply px-4 py-2 text-xs;
    }

    /* The arrow in a button or link nudges forward on hover (micro-interaction). */
    .btn .icon-arrow,
    .link-arrow .icon-arrow {
        @apply transition-transform duration-200;
    }

    .btn:hover .icon-arrow,
    .link-arrow:hover .icon-arrow {
        @apply translate-x-1;
    }

    /* Interactive text uses the darkened orange, which clears 4.5:1 on white. */
    .link-arrow {
        @apply inline-flex items-center gap-2 text-sm font-semibold text-text-brand;
    }

    /* ---------- Pills ---------- */

    .pill-active {
        @apply pill bg-primary text-text;
    }

    .pill-idle {
        @apply pill border border-border bg-surface text-text-secondary hover:border-primary hover:text-text;
    }

    .pill-muted {
        @apply pill bg-surface-muted text-text-secondary;
    }

    .pill-brand {
        @apply pill bg-primary-50 text-text-brand;
    }

    .pill-success {
        @apply pill bg-success/10 text-success;
    }

    .pill-warning {
        @apply pill bg-warning/10 text-warning;
    }

    .pill-error {
        @apply pill bg-error/10 text-error;
    }

    .pill-on-dark {
        @apply pill border border-white/20 text-white/90;
    }

    /* ---------- Surfaces ---------- */

    /* `relative` so a card can carry a full-surface stretched link. */
    .card-interactive {
        @apply card relative transition duration-300 hover:border-primary;
    }

    .panel {
        @apply rounded-2xl border border-border bg-surface p-6 sm:p-8;
    }

    .panel-dark {
        @apply rounded-2xl border border-white/10 bg-white/5 p-6 sm:p-8;
    }

    .hairline {
        @apply border-t border-border;
    }

    /* ---------- Media ---------- */

    .media-frame {
        @apply relative overflow-hidden rounded-2xl bg-surface-muted;
    }

    .media-frame img {
        @apply size-full object-cover;
    }

    /* Zoom on hover, used on cards whose whole surface is a link. */
    .media-zoom img {
        @apply transition-transform duration-700 ease-[cubic-bezier(0.16,1,0.3,1)];
    }

    .group:hover .media-zoom img {
        @apply scale-[1.04];
    }

    /* Legibility scrim for type sitting over photography. */
    .scrim {
        @apply pointer-events-none absolute inset-0;
        background: linear-gradient(to top, rgb(26 26 26 / 0.9) 0%, rgb(26 26 26 / 0.5) 38%, rgb(26 26 26 / 0.06) 72%);
    }

    .scrim-side {
        @apply pointer-events-none absolute inset-0;
        background: linear-gradient(100deg, rgb(26 26 26 / 0.94) 0%, rgb(26 26 26 / 0.74) 42%, rgb(26 26 26 / 0.28) 100%);
    }

    /* ---------- Forms ---------- */

    .form-label {
        @apply mb-1.5 block text-sm font-medium text-text;
    }

    .form-input {
        @apply block w-full rounded-lg border border-border bg-surface px-3.5 py-2.5 text-sm text-text
               transition placeholder:text-text-muted
               focus:border-primary focus:ring-2 focus:ring-primary/30;
    }

    .form-input-invalid {
        @apply border-error focus:border-error focus:ring-error/25;
    }

    .form-hint {
        @apply mt-1.5 text-xs text-text-muted;
    }

    .form-error {
        @apply mt-1.5 flex items-center gap-1.5 text-xs font-medium text-error;
    }

    /* ---------- Select2 ----------
       The plugin ships its own look, which belongs to no design system. Its
       markup is restyled here with the same tokens as `.form-input`, so an
       enhanced field is indistinguishable from a plain one. */

    .select2-container {
        @apply block w-full;
    }

    .select2-container .select2-selection--single,
    .select2-container .select2-selection--multiple {
        @apply flex min-h-11 w-full items-center rounded-lg border border-border bg-surface
               px-3.5 py-1.5 text-sm text-text transition;
    }

    .select2-container--focus .select2-selection--single,
    .select2-container--focus .select2-selection--multiple,
    .select2-container--open .select2-selection--single,
    .select2-container--open .select2-selection--multiple {
        @apply border-primary ring-2 ring-primary/30;
    }

    .select2-container .select2-selection--single .select2-selection__rendered {
        @apply p-0 leading-6 text-text;
    }

    .select2-container .select2-selection__placeholder {
        @apply text-text-muted;
    }

    .select2-container .select2-selection--single .select2-selection__arrow {
        @apply top-0 right-3 h-full w-4;
    }

    .select2-container .select2-selection--single .select2-selection__arrow b {
        @apply border-t-text-muted;
    }

    /* Multi-select values read as the same pills used elsewhere on the site. */
    .select2-container .select2-selection--multiple .select2-selection__rendered {
        @apply flex flex-wrap items-center gap-1.5 p-0;
    }

    .select2-container .select2-selection--multiple .select2-selection__choice {
        @apply m-0 flex items-center gap-1.5 rounded-md border-0 bg-surface-muted px-2 py-1 text-xs
               font-medium text-text;
    }

    .select2-container .select2-selection--multiple .select2-selection__choice__remove {
        @apply mr-0 border-0 bg-transparent text-base leading-none text-text-muted hover:text-error;
    }

    .select2-container .select2-search--inline .select2-search__field {
        @apply m-0 h-6 text-sm text-text placeholder:text-text-muted;
    }

    .select2-dropdown {
        @apply z-50 overflow-hidden rounded-lg border border-border bg-surface shadow-card;
    }

    .select2-container .select2-search--dropdown {
        @apply border-b border-border p-2;
    }

    .select2-container .select2-search--dropdown .select2-search__field {
        @apply w-full rounded-md border border-border bg-surface px-2.5 py-1.5 text-sm text-text
               outline-none focus:border-primary;
    }

    .select2-container .select2-results__option {
        @apply px-3.5 py-2 text-sm text-text;
    }

    .select2-container .select2-results__option--highlighted[aria-selected] {
        @apply bg-surface-muted text-text;
    }

    .select2-container .select2-results__option[aria-selected='true'] {
        @apply bg-primary/15 font-medium text-text;
    }

    .select2-container .select2-results__message {
        @apply px-3.5 py-2 text-sm text-text-muted;
    }

    /* ---------- Listings map ----------
       Leaflet renders its own markup, so the pin and the popup are styled here
       with the same tokens as everything else rather than left in the library's
       default blue. */

    .listing-marker__pin {
        @apply block size-4 rounded-full border-2 border-white bg-primary shadow-card;
    }

    .marker-cluster > div {
        @apply flex size-9 items-center justify-center rounded-full bg-primary
               font-display text-xs font-bold text-text shadow-card;
    }

    .marker-cluster {
        @apply bg-transparent;
    }

    .listing-popup {
        @apply block w-56 no-underline;
    }

    .listing-popup img {
        @apply mb-2 aspect-4/3 w-full rounded-lg object-cover;
    }

    .listing-popup__price {
        @apply block font-display text-sm font-bold text-text;
    }

    .listing-popup__title {
        @apply mt-0.5 block text-xs leading-snug text-text-secondary;
    }

    .listing-popup__facts {
        @apply mt-1 block text-xs text-text-muted;
    }

    .leaflet-container {
        @apply font-sans;
    }

    .leaflet-popup-content-wrapper {
        @apply rounded-xl border border-border shadow-raised;
    }

    .leaflet-popup-content {
        @apply m-3;
    }

    .prose-content {
        @apply prose prose-neutral max-w-none
               prose-headings:font-display prose-headings:text-text prose-headings:tracking-[-0.02em]
               prose-a:text-text-brand prose-a:underline-offset-4
               prose-strong:text-text prose-img:rounded-xl
               prose-blockquote:border-l-primary prose-blockquote:text-text-secondary;
    }

    /* ---------- Admin ---------- */

    .admin-nav-link {
        @apply flex items-center gap-2.5 rounded-lg px-3 py-2 text-sm text-white/70 transition
               hover:bg-white/10 hover:text-white;
    }

    .admin-nav-link-active {
        @apply bg-primary text-text hover:bg-primary;
    }

    .admin-card {
        @apply rounded-xl border border-border bg-surface;
    }

    .table-admin {
        @apply min-w-full divide-y divide-border text-sm;
    }

    .table-admin thead th {
        @apply bg-surface-muted px-4 py-3 text-left text-xs font-semibold uppercase tracking-wider text-text-secondary;
    }

    .table-admin tbody td {
        @apply px-4 py-3 align-middle text-text-secondary;
    }

    .table-admin tbody tr {
        @apply border-b border-border last:border-0 hover:bg-surface-muted/60;
    }

    /* Masonry children: CSS columns need explicit break control. */
    .masonry-item {
        @apply mb-4 break-inside-avoid;
    }

    /* ---------- Skeletons ---------- */

    .skeleton {
        @apply animate-pulse rounded-lg bg-surface-muted;
    }
}

@layer utilities {
    /*
     * Engineering texture: a faint drafting grid used behind technical sections.
     * Rendered with gradients rather than an image request.
     */
    .bg-blueprint {
        background-image:
            linear-gradient(to right, rgb(51 51 51 / 0.06) 1px, transparent 1px),
            linear-gradient(to bottom, rgb(51 51 51 / 0.06) 1px, transparent 1px);
        background-size: 56px 56px;
    }

    .bg-blueprint-dark {
        background-image:
            linear-gradient(to right, rgb(255 255 255 / 0.05) 1px, transparent 1px),
            linear-gradient(to bottom, rgb(255 255 255 / 0.05) 1px, transparent 1px);
        background-size: 56px 56px;
    }

    /* Survey dot matrix, for lighter technical backgrounds. */
    .bg-dot-grid {
        background-image: radial-gradient(rgb(51 51 51 / 0.16) 1px, transparent 1px);
        background-size: 22px 22px;
    }

    /* Topographic contours for land / GIS contexts. */
    .bg-topographic {
        background-image: repeating-radial-gradient(
            circle at 18% 82%,
            transparent 0 38px,
            rgb(255 154 46 / 0.10) 38px 39px
        );
    }

    /* Brand gradient surfaces. */
    .bg-gradient-primary { background-image: var(--gradient-primary); }
    .bg-gradient-primary-deep { background-image: var(--gradient-primary-deep); }
    .bg-gradient-brand-fusion { background-image: var(--gradient-brand-fusion); }
    .bg-gradient-dark { background-image: var(--gradient-dark); }
    .bg-gradient-dark-page { background-image: var(--gradient-dark-page); }
    .bg-gradient-surface { background-image: var(--gradient-surface); }
    .bg-gradient-warm-fade { background-image: var(--gradient-warm-fade); }
    .bg-gradient-hero-overlay { background-image: var(--gradient-hero-overlay); }

    /* Entrance states. motion.js clears these; the reduced-motion block above
       and the no-JS fallback in the layout reset them to the final state. */
    [data-reveal] {
        opacity: 0;
        transform: translateY(18px);
    }

    [data-reveal-child] {
        opacity: 0;
        transform: translateY(14px);
    }

    /* A pinned horizontal gallery fills the viewport for the length of its scroll. */
    [data-hscroll].is-pinned {
        @apply h-screen;
    }

    .marquee-track {
        animation: marquee var(--marquee-duration, 42s) linear infinite;
    }

    .marquee:hover .marquee-track {
        animation-play-state: paused;
    }
}

@keyframes marquee {
    from { transform: translateX(0); }
    to { transform: translateX(-50%); }
}

/* Slow cinematic drift on hero photography (Ken Burns). */
@keyframes slow-zoom {
    from { transform: scale(1); }
    to { transform: scale(1.08); }
}

.ken-burns {
    animation: slow-zoom 22s ease-out forwards;
}

@media (prefers-reduced-motion: reduce) {
    .ken-burns,
    .marquee-track {
        animation: none !important;
    }
}

/* Trix rich-text editor: align its chrome with the form controls above. */
trix-editor {
    @apply min-h-48 rounded-lg border border-border bg-surface px-3.5 py-2.5 text-sm text-text;
}

trix-toolbar .trix-button-group {
    @apply rounded-md border border-border;
}
