/* ------------------------------------------------------------------ * * Profile "more" threshold * * A full-bleed rule sits at the vertical centre of the handle. Everything * below it is tinted -- darker in light mode, lighter in dark mode -- so the * page reads as having a boundary you can cross. Crossing it reveals the * remaining sections in one motion. * ------------------------------------------------------------------ */ .threshold { position: relative; /* The rule is the vertical centre of this box, so the box is the hit area. */ width: 100%; height: 4em; display: flex; align-items: center; justify-content: center; margin: 0 0 8px 0; border: 0; padding: 0; background: none; font: inherit; color: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent; } .threshold:focus-visible { outline: none; } /* The tint itself is painted as the root background (see globals.css) -- an element tall enough to cover the rest of the page would extend the document's scrollable area. ProfileMore only publishes the line's position as `--threshold-y`. */ /* The rule itself. */ .threshold-rule { position: absolute; top: 50%; left: 0; width: 100%; height: 1px; pointer-events: none; transform: translateY(-0.5px); background: linear-gradient( to right, transparent 0%, var(--border) 12%, var(--border-strong) 50%, var(--border) 88%, transparent 100% ); transition: background var(--duration-slow) var(--ease-in-out); } .threshold[data-armed="true"] .threshold-rule { background: linear-gradient( to right, transparent 0%, var(--accent-bg) 6%, var(--accent) 50%, var(--accent-bg) 94%, transparent 100% ); } /* A soft glow that blooms out of the centre when the threshold is armed. */ .threshold-glow { position: absolute; top: 50%; left: 50%; width: 60%; height: 120px; pointer-events: none; transform: translate(-50%, -50%) scaleX(0.3); opacity: 0; background: radial-gradient( ellipse at center, var(--accent-bg) 0%, transparent 70% ); transition: opacity var(--duration-slow) var(--ease-out), transform var(--duration-slow) var(--ease-out); } .threshold[data-armed="true"] .threshold-glow { opacity: 1; transform: translate(-50%, -50%) scaleX(1); } /* The label pill. The rule passes behind it. */ .threshold-label { position: relative; z-index: 1; display: inline-flex; align-items: center; gap: 8px; padding: 6px 16px; border: 1px solid var(--border); border-radius: 999px; background: var(--bg); font-family: var(--mono); font-size: var(--text-xs); letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); white-space: nowrap; transition: color var(--duration-normal) var(--ease-in-out), border-color var(--duration-normal) var(--ease-in-out), background var(--duration-normal) var(--ease-in-out), transform var(--duration-slow) var(--ease-out); } /* Move the focus ring onto the pill -- the button itself is a full-width band. */ .threshold:focus-visible .threshold-label { outline: 2px solid var(--accent); outline-offset: 3px; } .threshold[data-armed="true"] .threshold-label { color: var(--accent); border-color: var(--accent); background: var(--bg-raised); transform: translateY(3px); } .threshold-chevron { width: 11px; height: 11px; flex-shrink: 0; transition: transform var(--duration-slow) var(--ease-out); } .threshold[data-armed="true"] .threshold-chevron { transform: translateY(2px); } .threshold[data-open="true"] .threshold-chevron { transform: rotate(180deg); } /* ---- the reveal ---- */ /* 0fr -> 1fr is the animatable stand-in for height:auto, so the sections can size themselves to their real content without any JS measurement. */ .more-reveal { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 700ms var(--ease-out); } .more-reveal[data-open="true"] { grid-template-rows: 1fr; } .more-reveal > .more-reveal-inner { overflow: hidden; min-height: 0; } .more-section { opacity: 0; transform: translateY(14px); transition: opacity 500ms var(--ease-out), transform 500ms var(--ease-out); } .more-reveal[data-open="true"] .more-section { opacity: 1; transform: translateY(0); } @media (prefers-reduced-motion: reduce) { .more-reveal, .more-section, .threshold-glow, .threshold-label, .threshold-chevron, .threshold-rule { transition-duration: 1ms !important; } .more-section { transition-delay: 0ms !important; transform: none; } }