/* Components shared by the public site and the staff workspace (DESIGN-SYSTEM.md §5).
   Colours, type and spacing come from tokens.css; no hard-coded hex values here. */
:root{
 /* Short aliases kept for older page rules (admin.css). New rules use the --c-*, --s-*, --r-* tokens directly. */
 --navy:var(--c-navy-800);--navy-700:var(--c-navy-600);--navy-050:var(--c-navy-050);
 --gold:var(--c-gold-500);--gold-700:var(--c-gold-700);--gold-100:var(--c-gold-100);
 --ivory:var(--c-ivory);--surface:var(--c-surface);--ink:var(--c-ink);--muted:var(--c-muted);--line:var(--c-line);
 --green:var(--c-success);--green-100:var(--c-success-100);--danger:var(--c-danger);--danger-100:var(--c-danger-100);--warning-100:var(--c-warning-100);
 --font-sans:var(--f-body);--font-serif:var(--f-display);
 --text-xs:var(--fs-label);--text-sm:13px;--text-md:var(--fs-small);--text-lg:18px;
 --space-1:var(--s-1);--space-2:var(--s-2);--space-3:var(--s-3);--space-4:var(--s-4);--space-5:var(--s-6);--space-6:var(--s-8);--space-7:var(--s-12);--space-8:var(--s-16);
 --radius-sm:var(--r-sm);--radius:var(--r-md);--radius-lg:var(--r-lg);--radius-pill:var(--r-pill);
 --shadow-sm:var(--shadow-1);--shadow:var(--shadow-2);--focus:var(--focus-ring);
 --page:var(--container);--gutter:clamp(16px,4vw,32px);
}

/* Brand mark (public header/footer and staff sidebar) */
.brand{display:flex;align-items:center;gap:var(--s-3);font-family:var(--f-display);font-weight:600;font-size:19px;line-height:1.1;letter-spacing:.1em;color:var(--c-navy-800);text-decoration:none;flex:none}
.brand:hover{color:var(--c-navy-800)}
.brand small{display:block;margin-top:3px;font:500 10.5px/1.4 var(--f-body);letter-spacing:.28em;color:var(--c-gold-700)}
.logo{width:52px;height:34px;fill:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round}
.logo-roof{stroke:var(--c-navy-800)}.logo-wave{stroke:var(--c-gold-500)}

/* Buttons: primary navy, gold (navy text), outline, text link. Minimum 44px, primary 48px. */
button,.button{display:inline-flex;align-items:center;justify-content:center;gap:var(--s-2);min-height:var(--tap);padding:10px 22px;border:1.5px solid transparent;border-radius:var(--r-md);background:var(--c-navy-800);color:var(--c-surface);font-weight:600;font-size:15px;line-height:1.2;text-decoration:none;cursor:pointer;transition:background-color .15s,border-color .15s,color .15s}
button:hover,.button:hover{background:var(--c-navy-600);color:var(--c-surface)}
button:disabled,.button[aria-disabled=true]{opacity:.6;cursor:not-allowed}
button[aria-busy=true]{cursor:progress}
.button-lg,button.button-lg{min-height:48px;padding:12px 26px}
.button.gold,button.gold{background:var(--c-gold-500);color:var(--c-navy-800)}
.button.gold:hover,button.gold:hover{background:var(--c-gold-700);color:var(--c-surface)}
.button.outline,button.outline{background:transparent;border-color:var(--c-navy-800);color:var(--c-navy-800)}
.button.outline:hover,button.outline:hover{background:var(--c-navy-800);color:var(--c-surface)}
.button.outline-light{background:transparent;border-color:var(--c-surface);color:var(--c-surface)}
.button.outline-light:hover{background:var(--c-surface);color:var(--c-navy-800)}
.button.light,.light{background:var(--c-surface);color:var(--c-navy-800)}
.secondary{background:var(--c-navy-050);color:var(--c-navy-800);min-height:36px;padding:7px 12px;border-radius:var(--r-sm)}
.secondary:hover{background:var(--c-line);color:var(--c-navy-800)}
.text-btn,.link-button{background:none;border:0;color:inherit;padding:0;min-height:0;font-weight:600;text-decoration:underline}
.link-button{color:var(--c-gold-700)}.text-btn:hover,.link-button:hover{background:none;color:var(--c-navy-800)}
.more-link{display:inline-flex;align-items:center;gap:6px;font-weight:600;font-size:15px;color:var(--c-gold-700);text-decoration:none}
.more-link:hover{color:var(--c-navy-800)}

/* Forms: real labels, 48px inputs, errors under the field */
label{display:flex;flex-direction:column;gap:6px;font-size:13px;color:var(--c-ink);font-weight:600}
input,select,textarea{width:100%;min-width:0;min-height:48px;padding:10px 14px;border:1px solid var(--c-input-line);border-radius:var(--r-md);background:var(--c-surface);color:var(--c-ink);font-weight:400;font-size:15px}
input::placeholder,textarea::placeholder{color:var(--c-muted);opacity:1}
textarea{min-height:120px;resize:vertical}
input[type=checkbox],input[type=radio]{width:auto;min-height:0;accent-color:var(--c-navy-800)}
input:focus-visible,select:focus-visible,textarea:focus-visible{border-color:var(--c-gold-500);border-radius:var(--r-md)}
[aria-invalid=true]{border-color:var(--c-danger);background:var(--c-danger-100)}
.field{display:flex;flex-direction:column;gap:6px;margin-bottom:var(--s-4)}
.field>label{display:block}
.req{color:var(--c-danger)}.opt{font-weight:400;color:var(--c-muted)}
.hint{margin:0;font-size:var(--fs-label);font-weight:400;color:var(--c-muted)}
.field-error{margin:0;font-size:13px;color:var(--c-danger);font-weight:600}
.field-error::before{content:"⚠ "}
.form-alert:focus{outline:none;box-shadow:var(--focus-ring)}
.check{flex-direction:row;align-items:flex-start;gap:var(--s-3);font-weight:400;font-size:14px}
.check input{margin-top:3px;width:20px;height:20px;flex:none}
fieldset{border:0;padding:0;margin:0 0 var(--s-4);min-width:0}
legend{font-weight:600;color:var(--c-ink);padding:0;margin-bottom:var(--s-1)}
.contact-group{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));column-gap:var(--s-4)}
.contact-group legend,.contact-group>.hint{grid-column:1/-1}.contact-group>.hint{margin-bottom:var(--s-3)}
.form-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px}
.enquiry .form-grid{grid-template-columns:repeat(2,minmax(0,1fr));column-gap:var(--s-4);row-gap:0}
.form-actions,.wide{grid-column:1/-1}
.form-success{text-align:center;padding:var(--s-6) 0}
.form-success:focus{outline:none}
.success-icon{display:inline-grid;place-items:center;width:52px;height:52px;margin:0 auto var(--s-3);border-radius:50%;background:var(--c-success-100);color:var(--c-success);font-size:26px;font-weight:700}

/* Panels and empty states */
.panel{padding:var(--s-6);background:var(--c-surface);border:1px solid var(--c-line);border-radius:var(--r-lg);margin-bottom:var(--s-6)}
.panel h2{font-size:24px}
.panel.success{text-align:center}
/* Staff sign-in and first-time setup render inside the public layout, so these live here, not in admin.css. */
.login{max-width:min(470px, calc(100% - 2 * var(--s-4)));margin:var(--s-16) auto;padding:var(--s-8) var(--s-6);box-shadow:var(--shadow-1)}
.login form{display:grid;gap:var(--s-4)}
.login form>button{justify-self:start}
.empty{border:1px dashed var(--c-input-line);border-radius:var(--r-lg);padding:var(--s-12) var(--s-6);text-align:center;background:var(--c-surface)}
.empty p{margin-top:0}

/* Public status badges: colour + icon + text. Ready = solid green + check; expected = white, dashed gold, clock. */
.badge{display:inline-flex;align-items:center;gap:6px;min-height:28px;padding:3px 12px;border-radius:var(--r-pill);font-size:var(--fs-label);font-weight:600;line-height:1.4;background:var(--c-surface);color:var(--c-ink);border:1.5px solid transparent;white-space:nowrap;max-width:100%}
.badge .icon{width:14px;height:14px;stroke-width:2}
.badge-ready{background:var(--c-success);color:var(--c-surface)}
.badge-soon{background:var(--c-surface);color:var(--c-gold-700);border:1.5px dashed var(--c-gold-500)}
.badge-sale{background:var(--c-navy-800);color:var(--c-surface)}
.badge-check{background:var(--c-surface);color:var(--c-navy-800);border-color:var(--c-line)}

/* Property card: 4:3 image, badge top-left, serif title, price per month, facts, location. Whole card is one link. */
.cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s-6)}
.property{position:relative;display:flex;flex-direction:column;min-width:0;background:var(--c-surface);border:1px solid var(--c-line);border-radius:var(--r-lg);overflow:hidden;box-shadow:var(--shadow-1);transition:box-shadow .2s,transform .2s}
.property:hover{box-shadow:var(--shadow-2);transform:translateY(-2px)}
.property:focus-within{box-shadow:var(--focus-ring)}
.property-media,.detail-media{position:relative;aspect-ratio:4/3;display:flex;align-items:flex-end;padding:var(--s-4);color:var(--c-surface);background:linear-gradient(150deg,var(--c-navy-050),var(--c-navy-600))}
.property-media>.badge,.gallery>.badge{position:absolute;top:var(--s-3);left:var(--s-3);z-index:1}
.detail-media{aspect-ratio:16/9;border-radius:var(--r-lg);margin-bottom:var(--s-6)}
.art-villa{background:linear-gradient(150deg,var(--c-success-100),var(--c-success))}
.art-house{background:linear-gradient(150deg,var(--c-gold-100),var(--c-gold-700))}
.art-land{background:linear-gradient(150deg,var(--c-sand-100),var(--c-gold-500))}
.art-label{display:flex;align-items:center;gap:var(--s-2);font-family:var(--f-display);font-size:20px;opacity:.95}
.art-icon{width:34px;height:34px;fill:none;stroke:currentColor;stroke-width:1.3}
.card-content{display:flex;flex-direction:column;gap:10px;padding:18px 20px 20px;min-width:0}
.card-content h3{margin:0;font-size:21px;line-height:1.3}
.card-content h3 a{color:var(--c-navy-800);text-decoration:none}
.stretched::after{content:"";position:absolute;inset:0}
.stretched:focus-visible{box-shadow:none}
.price{font-family:var(--f-body);font-size:22px;line-height:1.2;font-weight:600;color:var(--c-navy-800);margin:0;font-variant-numeric:tabular-nums}
.price small{font-size:14px;font-weight:400;color:var(--c-muted)}
.price.large{font-size:28px}
.facts{list-style:none;display:flex;flex-wrap:wrap;gap:var(--s-1) var(--s-4);padding:0;margin:0;font-size:13px;color:var(--c-muted)}
.facts li{display:flex;align-items:center;gap:6px}
.facts .icon{width:16px;height:16px}
.place{display:flex;align-items:center;gap:6px;margin:0;font-size:13px;color:var(--c-muted);min-width:0}
.has-photo{background:var(--c-navy-050);padding:0;overflow:hidden}
.has-photo img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.thumb img[hidden],.photo-item img[hidden],.has-photo img[hidden],.gallery-item img[hidden]{display:none}

/* Contact channels */
.channels{display:grid;gap:var(--s-2)}
.channel{display:flex;align-items:center;gap:var(--s-3);min-height:var(--tap);padding:var(--s-2) var(--s-3);border:1px solid var(--c-line);border-radius:var(--r-md);text-decoration:none;color:var(--c-ink)}
.channel:hover{border-color:var(--c-navy-800);color:var(--c-ink)}
.channel b,.channel small{display:block}.channel small{color:var(--c-muted);overflow-wrap:anywhere}.channel span{min-width:0}
.channel .icon{width:24px;height:24px}
.channel-whatsapp .icon{color:var(--c-whatsapp)}.channel-line .icon{color:var(--c-line-brand)}
.ticks{padding-left:0;list-style:none}.ticks li{padding-left:28px;position:relative;margin-bottom:var(--s-2)}
.ticks li::before{content:"✓";position:absolute;left:0;color:var(--c-success);font-weight:700}

@media (max-width:1023px){
 .cards{grid-template-columns:repeat(2,minmax(0,1fr))}
 .form-grid{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:639px){
 .cards,.contact-group,.enquiry .form-grid{grid-template-columns:1fr}
 .panel{padding:var(--s-4)}
}
@media (prefers-reduced-motion:reduce){.property:hover{transform:none}}

/* ---- Feedback, loading and motion (Master Design §04 buttons, §07 feedback) ---- */
/* Loading button: spinner + text, blocks repeat clicks (the server still deduplicates). */
button[aria-busy=true],.button[aria-busy=true]{cursor:progress;opacity:.85;pointer-events:none}
button[aria-busy=true]::before,.button[aria-busy=true]::before{content:"";width:16px;height:16px;flex:none;border-radius:50%;border:2.5px solid currentColor;border-right-color:transparent;animation:spin .8s linear infinite}
button:disabled:not([aria-busy=true]){background:var(--c-disabled);color:var(--c-muted);opacity:1}
@keyframes spin{to{transform:rotate(360deg)}}

/* Messages: success on white with a green check; error and conflict on tinted panels with an icon. */
.form-alert,.notice,.alert{margin:0 0 var(--s-4);display:flex;align-items:flex-start;gap:var(--s-3);padding:14px 18px;border:0;border-radius:12px;font-size:14px;line-height:1.5}
.form-alert::before,.notice::before,.alert::before{content:"";flex:none;width:22px;height:22px;background:currentColor;-webkit-mask:var(--alert-icon) center/contain no-repeat;mask:var(--alert-icon) center/contain no-repeat}
.form-alert{background:var(--c-danger-100);color:var(--c-danger-ink);font-weight:500;--alert-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 7v6M12 16.5v.5'/%3E%3C/svg%3E")}
.form-alert[hidden],.notice[hidden]{display:none}
.notice{background:var(--c-warning-100);color:var(--c-warning-ink);--alert-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M12 3l10 18H2z'/%3E%3Cpath d='M12 10v4M12 17v.5'/%3E%3C/svg%3E")}
.notice-success,.alert-success{background:var(--c-surface);color:var(--c-ink);border:1px solid var(--c-line);box-shadow:var(--shadow-1);--alert-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M8 12l3 3 5-6'/%3E%3C/svg%3E")}
.notice-success::before,.alert-success::before{background:var(--c-success)}
.alert-info{background:var(--c-info-100);color:var(--c-navy-800);--alert-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 11v6M12 7.5v.5'/%3E%3C/svg%3E")}
.form-alert:focus,.notice:focus{outline:none;box-shadow:var(--focus-ring)}

/* Toast: results confirmed by the server, bottom corner, slides in; stays until dismissed or 6 s pass. */
.toasts{position:fixed;right:var(--s-6);bottom:var(--s-6);z-index:60;display:grid;gap:var(--s-2);width:min(420px,calc(100vw - 32px));pointer-events:none}
.toast{pointer-events:auto;animation:toast-in .24s ease-out}
.toast.is-leaving{animation:toast-out .2s ease-in forwards}
.toast__close{margin-left:auto;min-height:28px;width:28px;padding:0;background:none;border:0;color:var(--c-muted);font-size:18px;line-height:1}
.toast__close:hover{background:var(--c-sand-100);color:var(--c-ink)}
@keyframes toast-in{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
@keyframes toast-out{to{opacity:0;transform:translateY(8px)}}

/* Skeleton loading */
.skeleton{border-radius:8px;background:linear-gradient(90deg,var(--st-blocked-a) 0%,var(--c-shimmer) 50%,var(--st-blocked-a) 100%) 0 0/200% 100%;animation:shimmer 1.2s ease-in-out infinite}
.skeleton-card{display:flex;flex-direction:column;background:var(--c-surface);border:1px solid var(--c-line);border-radius:var(--r-lg);overflow:hidden}
.skeleton--media{aspect-ratio:4/3;border-radius:0}
.skeleton-card__body{display:flex;flex-direction:column;gap:12px;padding:18px 20px 22px}
.skeleton--line{height:12px;border-radius:6px}.w70{width:70%}.w45{width:45%}.w85{width:85%}
@keyframes shimmer{from{background-position:100% 0}to{background-position:-100% 0}}
/* Photos fade in after decoding; the frame shimmers meanwhile (only when the script runs). */
.js .has-photo,.js .gallery-item{background:linear-gradient(90deg,var(--st-blocked-a) 0%,var(--c-shimmer) 50%,var(--st-blocked-a) 100%) 0 0/200% 100%;animation:shimmer 1.2s ease-in-out infinite}
.js .has-photo img,.js .gallery-item img,.js .hero-photo,.js .service-photo{opacity:0;transition:opacity .35s ease}
.js .has-photo img.is-loaded,.js .gallery-item img.is-loaded,.js .hero-photo.is-loaded,.js .service-photo.is-loaded{opacity:1}
.property:hover .has-photo img{transform:scale(1.03)}
.has-photo img{transition:opacity .35s ease,transform .4s ease}

/* Empty state: icon, short title and what to try next */
.empty{display:flex;flex-direction:column;align-items:center;gap:var(--s-2)}
.empty__icon{width:32px;height:32px;color:var(--c-gold-700);stroke-width:1.6}
.empty__title{margin:0;font-weight:600;color:var(--c-ink)}
.empty__hint{margin:0 0 var(--s-2);font-size:14px;color:var(--c-muted)}

/* Listing and contract status: dot + text */
.dot-status{display:inline-flex;align-items:center;gap:8px;font-size:14px}
.dot-status::before{content:"";width:8px;height:8px;border-radius:99px;background:var(--c-muted)}
.dot-status.is-published::before,.dot-status.is-confirmed::before{background:var(--c-success)}
.dot-status.is-hidden::before{background:var(--c-warning)}
.dot-status.is-ended::before{background:var(--c-navy-600)}
.dot-status.is-cancelled::before{background:var(--c-danger)}

@media (max-width:639px){.toasts{right:16px;bottom:88px}}
@media (prefers-reduced-motion:reduce){.js .has-photo img,.js .gallery-item img,.js .hero-photo,.js .service-photo{opacity:1}.skeleton,.js .has-photo,.js .gallery-item{animation:none}}
/* Uploaded logo: fixed height, natural width, never wider than the header allows. */
.brand--image{line-height:0}
.brand-img{display:block;height:48px;width:auto;max-width:min(240px,55vw);object-fit:contain}
.site-footer .brand-img{height:44px}
