/* portfolio-view.css -- /start/ PWA salon portfolio (wave 1, free plan).
   Companion to portfolio-view.js. PORTFOLIO-MASTER-PROMPT.md CP-B.

   RULES: design tokens from the PWA shell only (ugc-consent.html :root);
   no new colours, radii, shadows or easings. Reuses the global keyframes
   dashRowIn / shimmer / successPop / svcSheetSlideUp -- no new keyframes.
   All classes are pf- prefixed so nothing leaks into shell styles.
   ASCII only. British English in comments. */

/* ============================================================
   Shell + header
   ============================================================ */

#portfolioMode { padding-bottom: 48px; }

/* margin: 0, NOT 0 auto. The parent .mode-container is display:flex
   flex-direction:column, and auto cross-axis margins disable the
   default align-items:stretch on a flex item (CSS Flexbox spec).
   With margin:0 auto the wrap collapsed to its max-content width and
   centred -- so dismissing the "N new client approvals" chip (whose
   long phrase was the only wide max-content) shrank the entire screen
   to ~166px. The max-width:1200px is harmless inside a 420px mode-
   container and reserved for any future non-flex placement. */
.pf-wrap { max-width: 1200px; margin: 0; padding: 0 16px; }

/* D1: header re-platforms onto the house .page-header + .page-subtitle (defined
   in ugc-consent.html). portfolio-screen-tighten (2026-06-29): the piece-count
   line, the standalone Upload-photo CTA and the page-level publish card all
   collapsed into a single four-icon toolbar (.pf-toolbar-row) so the first
   viewport reads H1 + subtitle + toolbar + pictures. The old .pf-count, .pf-add-row,
   .pf-add-btn and .pf-publicpage-* rules are intentionally removed. */

/* ============================================================
   Sticky controls (R6): sentinel + IntersectionObserver adds
   .is-stuck for the glass treatment.
   ============================================================ */

.pf-controls-sentinel { height: 1px; }
.pf-controls { position: sticky; top: calc(env(safe-area-inset-top, 0px) + 57px); z-index: 20; display: flex; flex-direction: column; gap: 8px; padding: 8px 0; background: transparent; transition: box-shadow var(--transition-fast), background var(--transition-fast); }
.pf-controls.is-stuck { background: rgba(255, 255, 255, 0.85); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); box-shadow: var(--shadow-sm); margin: 0 -16px; padding-left: 16px; padding-right: 16px; }

/* portfolio-screen-tighten (2026-06-29): the four-icon toolbar that supersedes
   the old standalone Upload-photo CTA and the page-level publish card. Layout:
   [Upload] [Publish-or-Share] on the left; the existing .pf-view-toggle (Grid |
   Feed) floats right inside the same row via its own margin-left:auto. */
.pf-toolbar-row { display: flex; align-items: center; gap: 6px; }
.pf-toolbar-btn { display: inline-flex; align-items: center; justify-content: center; min-height: 38px; min-width: 44px; padding: 6px 12px; border: none; background: transparent; border-radius: var(--radius-full); color: var(--grey-700); cursor: pointer; transition: background var(--transition-fast), color var(--transition-fast), transform var(--transition-fast); }
.pf-toolbar-btn svg { width: 18px; height: 18px; }
.pf-toolbar-btn:hover { background: var(--grey-100); color: var(--grey-900); }
.pf-toolbar-btn:active { transform: scale(0.97); }

.pf-pill-row { display: flex; align-items: center; gap: 8px; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.pf-pill-row::-webkit-scrollbar { display: none; }

.pf-pill { flex: 0 0 auto; min-height: 44px; padding: 8px 16px; border-radius: var(--radius-full); border: 1px solid var(--grey-200); background: var(--white); color: var(--grey-600); font-family: var(--font-body); font-size: 0.8125rem; cursor: pointer; transition: background var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast); white-space: nowrap; }
.pf-pill.is-active { background: var(--teal-50); border-color: var(--teal-600); color: var(--teal-700); font-weight: 600; }

.pf-view-toggle { margin-left: auto; display: inline-flex; gap: 3px; padding: 3px; border-radius: var(--radius-full); background: var(--grey-100); flex: 0 0 auto; }
.pf-view-btn { border: none; background: transparent; min-height: 38px; min-width: 44px; padding: 6px 12px; border-radius: var(--radius-full); color: var(--grey-600); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; transition: background var(--transition-fast), color var(--transition-fast); }
.pf-view-btn.is-active { background: var(--white); color: var(--teal-700); box-shadow: var(--shadow-xs); }
.pf-view-btn svg { width: 18px; height: 18px; }

/* ============================================================
   Grid (R1-R4): pattern-first masonry. Aspect ratio is reserved
   with padding-bottom BEFORE any image loads (zero CLS).
   ============================================================ */

.pf-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; grid-auto-flow: dense; padding-top: 8px; }
@media (min-width: 768px) { .pf-grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1024px) { .pf-grid { grid-template-columns: repeat(4, 1fr); } }

.pf-card { position: relative; border-radius: var(--radius-xl); overflow: hidden; background: var(--grey-100); box-shadow: var(--shadow-xs); cursor: pointer; border: none; padding: 0; text-align: left; display: block; width: 100%; transition: transform var(--transition-fast); }
.pf-card:active { transform: scale(0.98); }

.pf-card-box { display: block; position: relative; width: 100%; height: 0; overflow: hidden; }
.pf-card-box.pf-fmt-portrait { padding-bottom: 125%; }
.pf-card-box.pf-fmt-square { padding-bottom: 100%; }
.pf-card-box.pf-fmt-landscape { padding-bottom: 62.5%; }
.pf-card-box.pf-fmt-vertical { padding-bottom: 177.78%; }
.pf-card.pf-fmt-vertical-card { grid-row: span 2; }

.pf-card-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }

/* D6/D27: shared image primitive -- DPR-sized full image fades up (blur-up
   over a tiny thumbnail when --blur), retries once on error, then drops to a
   quiet camera glyph. The wrapper fills any reserved-aspect parent box. */
.pf-img { position: absolute; inset: 0; display: block; overflow: hidden; background-size: cover; background-position: center; background-repeat: no-repeat; }
.pf-img--blur { background-color: var(--grey-100); }
.pf-img-full { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; opacity: 0; transition: opacity 0.35s var(--ease-out-expo); }
.pf-img-full.is-loaded { opacity: 1; }
.pf-img-fallback { position: absolute; inset: 0; display: none; align-items: center; justify-content: center; background: var(--grey-100); color: var(--grey-400); }
.pf-img-fallback svg { width: 28px; height: 28px; }
.pf-img-failed .pf-img-full { display: none; }
.pf-img-failed .pf-img-fallback { display: flex; }

.pf-card-scrim { position: absolute; left: 0; right: 0; bottom: 0; height: 45%; background: linear-gradient(to top, rgba(15, 23, 42, 0.62) 0%, rgba(15, 23, 42, 0) 100%); pointer-events: none; }

.pf-card-title { position: absolute; left: 10px; right: 10px; bottom: 8px; color: var(--white); font-family: var(--font-body); font-size: 0.8125rem; font-weight: 500; line-height: 1.35; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; text-shadow: 0 1px 2px rgba(15, 23, 42, 0.4); }

.pf-card-badge { position: absolute; top: 8px; right: 8px; display: inline-flex; align-items: center; gap: 4px; padding: 3px 8px; border-radius: var(--radius-full); background: rgba(15, 23, 42, 0.7); color: var(--white); font-family: var(--font-body); font-size: 0.6875rem; font-variant-numeric: tabular-nums; pointer-events: none; }
.pf-card-badge svg { width: 12px; height: 12px; }
.pf-card-badge + .pf-card-badge { top: 36px; }

.pf-card.pf-entrance { animation: dashRowIn 0.3s var(--ease-out-expo) both; }
.pf-card.pf-pop { animation: successPop 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275); }

/* Skeletons: emitted in the SAME 8-step pattern as real cards. */
.pf-skel { position: relative; border-radius: var(--radius-xl); overflow: hidden; background: var(--grey-100); }
.pf-skel::after { content: ""; position: absolute; inset: 0; background: linear-gradient(90deg, transparent 0%, rgba(255, 255, 255, 0.6) 50%, transparent 100%); background-size: 200% 100%; animation: shimmer 1.4s infinite; }

/* ============================================================
   Feed view (R5 / P22): single-column editorial list.
   ============================================================ */

.pf-feed { display: flex; flex-direction: column; gap: 28px; padding-top: 8px; max-width: 560px; margin: 0 auto; }
/* D26: the feed row is an <article>, not a button. */
.pf-feed-item { display: block; }

/* The media zone holds the slider (multi-photo) or a static framed image
   (single). It is tappable but is NOT a button (no nested interactives). */
.pf-feed-media-zone { position: relative; }
.pf-feed-media-zone.is-tappable { cursor: pointer; }
.pf-feed-media { display: block; position: relative; aspect-ratio: 4 / 5; border-radius: var(--radius-xl); overflow: hidden; background: var(--grey-100); box-shadow: var(--shadow-xs); }
/* D28: the count badge sits above the slider progress + imagery. */
.pf-feed-badge { z-index: 3; }
/* Single-photo video rows show a centred video glyph (playback is in detail). */
.pf-feed-vbadge { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 52px; height: 52px; border-radius: var(--radius-full); background: rgba(15, 23, 42, 0.55); color: var(--white); display: flex; align-items: center; justify-content: center; pointer-events: none; }
.pf-feed-vbadge svg { width: 24px; height: 24px; }

/* D26: the single explicit open-detail affordance, carrying the card content. */
.pf-feed-open { display: block; width: 100%; border: none; background: transparent; text-align: left; cursor: pointer; padding: 10px 2px 0; }
.pf-feed-eyebrow { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin-bottom: 5px; }
.pf-feed-eyebrow:empty { display: none; }
.pf-feed-meta { font-family: var(--font-body); font-size: 0.6875rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--grey-500); }
.pf-feed-person { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; border-radius: var(--radius-full); background: var(--coral-50); color: var(--coral-700); font-family: var(--font-body); font-size: 0.6875rem; font-weight: 600; }
.pf-feed-person svg { width: 13px; height: 13px; }
.pf-feed-title { font-family: var(--font-display); font-weight: 400; font-size: 1.375rem; line-height: 1.2; color: var(--grey-900); margin: 0 0 4px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* D27: feed caption is the description clamped to 2 lines -- never the detail
   sheet's pre-wrap rule (that is for full text). */
.pf-feed-caption { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; font-family: var(--font-body); font-size: 0.875rem; color: var(--grey-600); line-height: 1.5; margin: 0; }

/* D27: feed-shaped skeletons (the grid skeletons do not fit a single column). */
.pf-feed-skel { display: flex; flex-direction: column; gap: 8px; }
.pf-feed-skel-media { aspect-ratio: 4 / 5; border-radius: var(--radius-xl); }
.pf-feed-skel-line { height: 14px; border-radius: var(--radius-full); }
.pf-feed-skel-line--short { width: 55%; }

/* ============================================================
   States (4.5)
   ============================================================ */

.pf-empty { text-align: center; padding: 56px 24px; }
.pf-empty-icon { width: 56px; height: 56px; margin: 0 auto 16px; border-radius: var(--radius-full); background: var(--teal-50); color: var(--teal-600); display: flex; align-items: center; justify-content: center; }
.pf-empty-icon svg { width: 26px; height: 26px; }
.pf-empty-title { font-family: var(--font-display); font-weight: 400; font-size: 1.5rem; color: var(--grey-900); margin: 0 0 8px; }
.pf-empty-hint { font-family: var(--font-body); font-size: 0.875rem; color: var(--grey-600); line-height: 1.6; max-width: 44ch; margin: 0 auto 20px; }
.pf-empty-nudge { display: inline-block; margin-bottom: 16px; padding: 6px 14px; border-radius: var(--radius-full); background: var(--teal-50); color: var(--teal-700); font-family: var(--font-body); font-size: 0.8125rem; font-weight: 600; font-variant-numeric: tabular-nums; }

/* D27: filters matched nothing -- reuse the empty chassis, tighter. */
.pf-empty--filtered { padding: 40px 24px; }
.pf-empty--filtered .pf-empty-hint { margin-bottom: 16px; }

/* D32: the OWNER empty state is editorial -- generous whitespace, a larger
   display-serif title, and a low-opacity preview plate of three format tiles
   (the 8-step pattern) hinting at the gallery to come. */
.pf-empty--owner { padding: 40px 24px 64px; }
.pf-empty-preview { display: flex; align-items: flex-end; justify-content: center; gap: 12px; max-width: 320px; margin: 0 auto 36px; opacity: 0.14; pointer-events: none; }
.pf-empty-tile { flex: 1 1 0; border-radius: var(--radius-lg); background: var(--grey-400); }
.pf-empty--owner .pf-empty-title { font-size: 1.875rem; letter-spacing: -0.01em; margin: 0 0 10px; }
.pf-empty--owner .pf-empty-hint { font-size: 0.9375rem; }

.pf-error { border: 1px dashed var(--grey-300); border-radius: var(--radius-xl); padding: 32px 24px; text-align: center; margin-top: 16px; }
.pf-error p { font-family: var(--font-body); font-size: 0.875rem; color: var(--grey-600); margin: 0 0 16px; }

.pf-offline-banner { display: flex; align-items: center; justify-content: center; gap: 8px; padding: 8px 16px; background: var(--warning-light); color: var(--grey-700); font-family: var(--font-body); font-size: 0.8125rem; border-radius: var(--radius-lg); margin: 8px 0; }

.pf-btn-secondary { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 44px; padding: 10px 20px; border-radius: var(--radius-full); border: 1px solid var(--grey-200); background: var(--white); color: var(--grey-700); font-family: var(--font-body); font-size: 0.875rem; font-weight: 600; cursor: pointer; transition: background var(--transition-fast), border-color var(--transition-fast); }
.pf-btn-secondary:active { background: var(--grey-50); }

/* ============================================================
   Bottom sheets (detail / edit / confirm). Shared chassis,
   svcSheetSlideUp entrance (global keyframe).
   ============================================================ */

.pf-sheet-backdrop { position: fixed; inset: 0; background: rgba(15, 23, 42, 0.45); z-index: 1200; opacity: 0; transition: opacity 0.25s ease; }
.pf-sheet-backdrop.is-open { opacity: 1; }

.pf-sheet { position: fixed; left: 0; right: 0; bottom: 0; z-index: 1201; background: var(--white); border-radius: 20px 20px 0 0; box-shadow: var(--shadow-xl); max-height: 92dvh; display: flex; flex-direction: column; padding-bottom: env(safe-area-inset-bottom, 0px); animation: svcSheetSlideUp var(--transition-base); }
.pf-sheet-handle { width: 36px; height: 4px; border-radius: var(--radius-full); background: var(--grey-300); margin: 10px auto 4px; flex: 0 0 auto; }

.pf-sheet-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 16px 10px; flex: 0 0 auto; }
.pf-sheet-head-title { font-family: var(--font-display); font-weight: 400; font-size: 1.125rem; color: var(--grey-900); margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pf-sheet-iconbtn { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; border: none; border-radius: var(--radius-full); background: var(--grey-100); color: var(--grey-700); cursor: pointer; flex: 0 0 auto; transition: background var(--transition-fast); }
.pf-sheet-iconbtn:active { background: var(--grey-200); }
.pf-sheet-iconbtn svg { width: 18px; height: 18px; }
/* D27: replaces inline width:44px head spacers that balance the icon button. */
.pf-sheet-spacer { width: 44px; flex: 0 0 auto; }

.pf-sheet-body { overflow-y: auto; -webkit-overflow-scrolling: touch; flex: 1 1 auto; }

/* ============================================================
   Detail sheet (R8-R11) + carousel (P16 spike-proven mechanics)
   ============================================================ */

.pf-carousel { position: relative; overflow: hidden; background: var(--grey-900); transition: height 0.25s var(--ease-out-expo); }
.pf-carousel-track { display: flex; height: 100%; overflow-x: auto; overflow-y: hidden; scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.pf-carousel-track::-webkit-scrollbar { display: none; }
.pf-slide { position: relative; flex: 0 0 100%; min-width: 100%; scroll-snap-align: center; scroll-snap-stop: always; display: flex; align-items: center; justify-content: center; }
.pf-slide img, .pf-slide video { width: 100%; height: 100%; object-fit: contain; display: block; }

.pf-carousel-dots { position: absolute; left: 0; right: 0; bottom: 8px; display: flex; justify-content: center; gap: 6px; pointer-events: none; padding: 14px 0 2px; background: linear-gradient(to top, rgba(15, 23, 42, 0.35), transparent); }
.pf-carousel-dot { width: 10px; height: 10px; border-radius: 50%; background: rgba(255, 255, 255, 0.55); transition: transform var(--transition-fast), background var(--transition-fast); }
.pf-carousel-dot.is-active { background: var(--teal-400); transform: scale(1.2); }
/* D27: scaled-dot treatment past 8 -- taper near the window edge, hide beyond. */
.pf-dots-many .pf-carousel-dot { width: 8px; height: 8px; }
.pf-carousel-dot.pf-dot-s1 { transform: scale(0.66); }
.pf-carousel-dot.pf-dot-s1.is-active { transform: scale(0.85); }
.pf-carousel-dot.pf-dot-s2 { transform: scale(0.4); }
.pf-carousel-dot.pf-dot-hidden { display: none; }
/* D27: carousel image error fallback (dark slide keeps the glyph legible). */
.pf-slide-fallback { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: var(--grey-500); background: var(--grey-900); }
.pf-slide-fallback svg { width: 36px; height: 36px; }

.pf-video-toggle { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 56px; height: 56px; border-radius: var(--radius-full); background: rgba(15, 23, 42, 0.55); color: var(--white); display: flex; align-items: center; justify-content: center; pointer-events: none; opacity: 0; transition: opacity var(--transition-fast); }
.pf-video-toggle.is-visible { opacity: 1; }
.pf-video-toggle svg { width: 24px; height: 24px; }

.pf-detail-content { padding: 16px; }
.pf-chip { display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px; border-radius: var(--radius-full); background: var(--teal-50); color: var(--teal-700); font-family: var(--font-body); font-size: 0.75rem; font-weight: 600; }
.pf-chip svg { width: 16px; height: 16px; }
.pf-chip--person { background: var(--coral-50); color: var(--coral-700); }
.pf-detail-title { font-family: var(--font-display); font-weight: 400; font-size: 1.5rem; color: var(--grey-900); margin: 10px 0 6px; }
.pf-detail-desc { font-family: var(--font-body); font-size: 0.875rem; color: var(--grey-600); line-height: 1.6; margin: 0 0 10px; white-space: pre-wrap; }
.pf-detail-meta { font-family: var(--font-body); font-size: 0.8125rem; color: var(--grey-500); font-variant-numeric: tabular-nums; display: flex; flex-wrap: wrap; gap: 4px 14px; }

.pf-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; padding: 14px 16px calc(14px + env(safe-area-inset-bottom, 0px)); border-top: 1px solid var(--grey-100); }

.pf-vis-toggle { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 8px 16px; border-radius: var(--radius-full); border: none; cursor: pointer; font-family: var(--font-body); font-size: 0.8125rem; font-weight: 600; transition: background var(--transition-fast), color var(--transition-fast), transform var(--transition-fast); background: var(--grey-100); color: var(--grey-600); }
.pf-vis-toggle.is-public { background: var(--gradient-brand); color: var(--white); }

.pf-btn-tertiary { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 8px 14px; border: none; border-radius: var(--radius-full); background: transparent; color: var(--grey-600); font-family: var(--font-body); font-size: 0.8125rem; font-weight: 600; cursor: pointer; transition: background var(--transition-fast), color var(--transition-fast); }
.pf-btn-tertiary:active { background: var(--grey-100); }
.pf-btn-tertiary svg { width: 16px; height: 16px; }
.pf-btn-tertiary--danger:hover, .pf-btn-tertiary--danger:active { background: #fef2f2; color: #dc2626; }

/* ============================================================
   Edit sheet (4.4): PWA form patterns.
   ============================================================ */

.pf-form { padding: 4px 16px 16px; display: flex; flex-direction: column; gap: 14px; }
.pf-field label { display: block; font-family: var(--font-body); font-size: 0.8125rem; font-weight: 600; color: var(--grey-700); margin-bottom: 6px; }
.pf-field input[type="text"], .pf-field textarea, .pf-field select { width: 100%; box-sizing: border-box; padding: 16px 18px; border: 1px solid var(--grey-200); border-radius: var(--radius-lg); font-family: var(--font-body); font-size: 0.9375rem; color: var(--grey-900); background: var(--white); transition: border-color var(--transition-fast), box-shadow var(--transition-fast); }
.pf-field input:focus, .pf-field textarea:focus, .pf-field select:focus { outline: none; border-color: var(--teal-600); box-shadow: 0 0 0 4px rgba(14, 124, 123, 0.1); }
.pf-field textarea { min-height: 140px; resize: vertical; }
.pf-field select { appearance: none; -webkit-appearance: none; background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23475569' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 14px center; padding-right: 42px; }

.pf-toggle-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 0; }
.pf-toggle-row-label { font-family: var(--font-body); font-size: 0.875rem; color: var(--grey-700); }
.pf-switch { position: relative; width: 48px; height: 28px; flex: 0 0 auto; border: none; border-radius: var(--radius-full); background: var(--grey-200); cursor: pointer; transition: background var(--transition-fast); }
.pf-switch::after { content: ""; position: absolute; top: 3px; left: 3px; width: 22px; height: 22px; border-radius: var(--radius-full); background: var(--white); box-shadow: var(--shadow-xs); transition: transform var(--transition-fast); }
.pf-switch.is-on { background: var(--teal-600); }
.pf-switch.is-on::after { transform: translateX(20px); }

.pf-btn-primary { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 48px; padding: 12px 22px; border: none; border-radius: var(--radius-full); background: var(--gradient-brand); color: var(--white); font-family: var(--font-body); font-size: 0.9375rem; font-weight: 600; cursor: pointer; box-shadow: var(--shadow-teal); transition: transform var(--transition-fast), opacity var(--transition-fast); }
.pf-btn-primary:active { transform: scale(0.98); }
.pf-btn-primary[disabled] { opacity: 0.5; cursor: default; }
.pf-btn-danger { background: #dc2626; box-shadow: var(--shadow-coral); }

/* Confirm sheet */
.pf-confirm { padding: 8px 20px calc(20px + env(safe-area-inset-bottom, 0px)); text-align: center; }
.pf-confirm-title { font-family: var(--font-display); font-weight: 400; font-size: 1.375rem; color: var(--grey-900); margin: 6px 0 8px; }
.pf-confirm-body { font-family: var(--font-body); font-size: 0.875rem; color: var(--grey-600); line-height: 1.6; margin: 0 0 18px; }
.pf-confirm-actions { display: flex; gap: 10px; justify-content: center; }

/* ============================================================
   Add-work tray (4.3) + upload-success offer (C7)
   ============================================================ */

.pf-tray-section { font-family: var(--font-body); font-size: 0.6875rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--grey-500); margin: 16px 16px 8px; }
.pf-tray-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; padding: 0 16px; }
.pf-tray-loading { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; padding: 16px; }
.pf-tray-skel { aspect-ratio: 1 / 1; }

.pf-tile { position: relative; aspect-ratio: 1 / 1; border: none; padding: 0; border-radius: var(--radius-lg); overflow: hidden; background: var(--grey-100); cursor: pointer; transition: transform var(--transition-fast); }
.pf-tile:active { transform: scale(0.97); }
.pf-tile img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.pf-tile.is-selected { outline: 3px solid var(--teal-600); outline-offset: -3px; }
.pf-tile-order { position: absolute; top: 6px; left: 6px; min-width: 22px; height: 22px; padding: 0 4px; border-radius: var(--radius-full); background: var(--teal-600); color: var(--white); font-family: var(--font-body); font-size: 0.75rem; font-weight: 700; display: flex; align-items: center; justify-content: center; font-variant-numeric: tabular-nums; }
.pf-tile-order:empty { display: none; }
.pf-tile-marks { position: absolute; top: 6px; right: 6px; display: flex; gap: 4px; }
.pf-tile-mark { width: 22px; height: 22px; border-radius: var(--radius-full); background: rgba(15, 23, 42, 0.65); color: var(--white); display: inline-flex; align-items: center; justify-content: center; }
.pf-tile-mark svg { width: 12px; height: 12px; }
.pf-tile-area { position: absolute; left: 6px; bottom: 6px; max-width: calc(100% - 12px); padding: 3px 8px; border-radius: var(--radius-full); background: rgba(15, 23, 42, 0.55); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); color: var(--white); font-family: var(--font-body); font-size: 0.6875rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pf-tile.is-added { opacity: 0.45; cursor: default; }
.pf-tile-added { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: rgba(255, 255, 255, 0.35); color: var(--grey-900); font-family: var(--font-body); font-size: 0.8125rem; font-weight: 700; }

.pf-tray-footer { position: sticky; bottom: 0; background: var(--white); }
.pf-tray-footer .pf-btn-primary { width: 100%; }

.pf-upload-offer { position: fixed; left: 12px; right: 12px; bottom: calc(16px + env(safe-area-inset-bottom, 0px)); z-index: 1300; display: flex; align-items: center; gap: 10px; padding: 10px 12px; background: var(--white); border: 1px solid var(--grey-200); border-radius: var(--radius-xl); box-shadow: var(--shadow-lg); animation: svcSheetSlideUp var(--transition-base); }
.pf-upload-offer-text { flex: 1 1 auto; font-family: var(--font-body); font-size: 0.8125rem; color: var(--grey-700); }
.pf-upload-offer-btn { min-height: 40px; padding: 8px 14px; font-size: 0.8125rem; }
@media (min-width: 560px) { .pf-upload-offer { left: auto; right: 16px; max-width: 420px; } }

/* ============================================================
   Publish moment (D19) + auto-publish switch (D15)
   ============================================================ */

.pf-publish-body { font-family: var(--font-body); font-size: 0.875rem; color: var(--grey-600); line-height: 1.6; margin: 4px 16px 4px; }
.pf-pubgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; padding: 0 16px 16px; }
.pf-pubtile { position: relative; aspect-ratio: 1 / 1; border: none; padding: 0; border-radius: var(--radius-lg); overflow: hidden; background: var(--grey-100); cursor: pointer; transition: transform var(--transition-fast); }
.pf-pubtile:active { transform: scale(0.97); }
.pf-pubtile.is-selected { outline: 3px solid var(--teal-600); outline-offset: -3px; }
.pf-pubtile[disabled] { cursor: default; }
.pf-pubtile-media { position: absolute; inset: 0; display: block; }
.pf-pubtile-order { position: absolute; top: 6px; left: 6px; width: 22px; height: 22px; border-radius: var(--radius-full); background: rgba(15, 23, 42, 0.45); }
.pf-pubtile.is-selected .pf-pubtile-order { background: var(--teal-600); }
.pf-pubtile-flag { position: absolute; left: 0; right: 0; bottom: 0; padding: 4px 6px; background: rgba(14, 124, 123, 0.85); color: var(--white); font-family: var(--font-body); font-size: 0.625rem; font-weight: 700; text-align: center; letter-spacing: 0.04em; text-transform: uppercase; }

/* ============================================================
   Consent ready-to-add chip (D31)
   ============================================================ */

.pf-consent-chip { display: flex; align-items: stretch; gap: 0; margin: 0 0 12px; border: 1px solid var(--teal-200); background: var(--teal-50); border-radius: var(--radius-full); overflow: hidden; animation: dashRowIn 0.3s var(--ease-out-expo) both; }
.pf-consent-chip-main { flex: 1 1 auto; display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 8px 16px; border: none; background: transparent; color: var(--teal-700); font-family: var(--font-body); font-size: 0.8125rem; font-weight: 600; cursor: pointer; text-align: left; }
.pf-consent-chip-main svg { width: 16px; height: 16px; flex: 0 0 auto; }
.pf-consent-chip-x { flex: 0 0 auto; width: 44px; border: none; background: transparent; color: var(--teal-700); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.pf-consent-chip-x svg { width: 16px; height: 16px; }

/* ============================================================
   Copy-link control (CP6, D10): selectable middle-truncated URL + copy
   ============================================================ */

.pf-copylink-row { padding: 6px 16px 14px; }
.pf-copylink { display: flex; align-items: center; gap: 8px; padding: 6px 6px 6px 14px; border: 1px solid var(--grey-200); border-radius: var(--radius-full); background: var(--grey-50); }
.pf-copylink-url { display: flex; min-width: 0; flex: 1 1 auto; font-family: var(--font-body); font-size: 0.8125rem; color: var(--grey-700); -webkit-user-select: text; user-select: text; }
.pf-copylink-head { flex: 0 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pf-copylink-tail { flex: 0 0 auto; white-space: nowrap; }
.pf-copylink-btn { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px; min-height: 36px; padding: 6px 14px; border: none; border-radius: var(--radius-full); background: var(--teal-600); color: var(--white); font-family: var(--font-body); font-size: 0.8125rem; font-weight: 600; cursor: pointer; }
.pf-copylink-btn svg { width: 15px; height: 15px; }

/* ============================================================
   Accessibility + reduced motion
   ============================================================ */

.pf-pill:focus-visible, .pf-view-btn:focus-visible, .pf-card:focus-visible,
.pf-feed-item:focus-visible, .pf-toolbar-btn:focus-visible, .pf-sheet-iconbtn:focus-visible,
.pf-vis-toggle:focus-visible, .pf-btn-primary:focus-visible, .pf-btn-secondary:focus-visible,
.pf-btn-tertiary:focus-visible, .pf-switch:focus-visible {
  outline: 2px solid var(--teal-600); outline-offset: 2px;
}

/* D27: hover affordances live behind (hover: hover) so touch devices never get
   stuck hover states. */
@media (hover: hover) {
  .pf-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-sm); }
  .pf-pill:hover { border-color: var(--grey-300); color: var(--grey-800); }
  .pf-view-btn:hover { color: var(--teal-700); }
  .pf-btn-secondary:hover { background: var(--grey-50); }
  .pf-btn-tertiary:hover { background: var(--grey-100); }
  .pf-tile:hover { transform: scale(0.99); }
}

@media (prefers-reduced-motion: reduce) {
  .pf-card.pf-entrance, .pf-card.pf-pop { animation: none; }
  .pf-sheet { animation: none; }
  .pf-carousel { transition: none; }
  .pf-card, .pf-toolbar-btn, .pf-btn-primary { transition: none; }
  .pf-img-full { transition: none; }
}

/* ============================================================
   CP2 (portfolio-auto-populate-share): virtual-item chip + first-open modal.
   Token-only -- no new colours, radii, shadows or keyframes.
   ============================================================ */

/* Per-card chip on virtual (serve-time-synthesised) items. Sits as an
   absolutely-positioned overlay in the top-left of the card / feed article.
   Owner-view only (the public surface filters out visibility:'private'). */
.pf-virtual-chip { position: absolute; top: 8px; left: 8px; z-index: 2; display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: var(--radius-full); background: var(--grey-100); color: var(--grey-800); font-family: var(--font-body); font-size: 0.7rem; font-weight: 600; letter-spacing: 0.02em; box-shadow: var(--shadow-sm); border: 1px solid var(--grey-200); pointer-events: none; max-width: calc(100% - 16px); }
.pf-virtual-chip svg { width: 12px; height: 12px; color: var(--grey-600); flex-shrink: 0; }
.pf-virtual-chip-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* The card / feed article needs position:relative for the chip overlay
   to anchor. The existing .pf-card is a button (default position:static);
   add it conditionally to articles that mark a source kind. */
[data-source-kind] { position: relative; }

/* CP2 first-open onboarding modal. Sits over the whole screen with a
   semi-translucent backdrop. Card-style body with two actions. */
.pf-onboard-modal { position: fixed; inset: 0; z-index: 1000; display: flex; align-items: flex-end; justify-content: center; }
.pf-onboard-backdrop { position: absolute; inset: 0; background: rgba(15, 23, 42, 0.45); }
.pf-onboard-card { position: relative; z-index: 1; width: 100%; max-width: 420px; box-sizing: border-box; padding: 24px 20px 20px; background: var(--white); border-top-left-radius: var(--radius-lg); border-top-right-radius: var(--radius-lg); box-shadow: var(--shadow-md); }
.pf-onboard-title { margin: 0 0 8px; font-family: var(--font-display); font-size: 1.125rem; color: var(--grey-900); }
.pf-onboard-body { margin: 0 0 18px; font-family: var(--font-body); font-size: 0.875rem; color: var(--grey-700); line-height: 1.45; }
.pf-onboard-count { color: var(--grey-500); font-variant-numeric: tabular-nums; }
.pf-onboard-actions { display: flex; flex-direction: row-reverse; gap: 10px; }
.pf-onboard-actions .pf-btn-primary, .pf-onboard-actions .pf-btn-secondary { flex: 1; min-height: 44px; }

@media (min-width: 480px) {
  .pf-onboard-modal { align-items: center; padding: 16px; }
  .pf-onboard-card { border-radius: var(--radius-lg); max-width: 380px; }
}

/* CP3 (portfolio-auto-populate-share, DA5) -- SUPERSEDED 2026-06-29 by
   portfolio-screen-tighten. The page-level "Your public page" card collapsed
   into a single contextual toolbar icon on .pf-toolbar-row, so .pf-publicpage-*
   styling is intentionally removed. See plan.md D38 in
   runs/portfolio-screen-tighten/. */

/* Pre-P5.b (portfolio auto-populate wave-2): branded-gradient fallback shown
   in the same #pfPublicPageCard mount when the server refuses auto-populate
   (client_media_consent_captured_at not yet captured for this salon). Tokens
   only, matching the brand gradient used elsewhere (e.g. .cal-thumb-wrap). */
.pf-consent-gate-card { margin: 0 0 12px; padding: 14px 16px; border-radius: var(--radius-lg); background: linear-gradient(135deg, var(--teal-600), var(--coral-400)); box-shadow: var(--shadow-sm); }
.pf-consent-gate-text { margin: 0; color: var(--white); font-family: var(--font-body); font-size: 0.8125rem; font-weight: 600; line-height: 1.4; }
