/* ============================================================================ Tangled — Discover Visual system: Linear (DESIGN.md) — dark canvas, surface ladder, hairlines, negative-tracked type. Single chromatic accent swapped to Tangled teal. ========================================================================== */ :root { /* ---- Surface ladder (canvas -> 4) ---------------------------------- */ --canvas: #010102; /* deepest dark, faint blue tint — never #000 */ --surface-1: #0d0e10; /* cards, panels, screenshot frames */ --surface-2: #141519; /* featured / hovered cards */ --surface-3: #1b1d22; /* sub-nav, dropdowns */ --surface-4: #23262c; /* deepest lifted surface */ /* ---- Hairlines ----------------------------------------------------- */ --hairline: #23252a; --hairline-strong: #2e3138; --hairline-tertiary: #1a1c20; /* ---- Box edges: black perimeter by default + outer glow on hover --- */ --edge-dark: #050506; --glow-hover: 0 0 16px 0 rgba(255, 255, 255, 0.04); /* ---- Text ---------------------------------------------------------- */ --ink: #f7f8f8; --ink-muted: #d0d6e0; --ink-subtle: #8a8f98; --ink-tertiary: #62666d; /* ---- Accent — Tangled teal (the single chromatic accent) ----------- */ --accent: #1fb8a6; --accent-hover: #34d6c3; --accent-pressed: #189e8e; --accent-focus: #1fb8a6; --on-accent: #04130f; /* dark ink on teal for contrast */ --accent-tint: rgba(31, 184, 166, 0.12); --accent-tint-border: rgba(31, 184, 166, 0.28); /* ---- Semantic ------------------------------------------------------ */ --success: #27a644; /* ---- Functional language dot colors (kept small) ------------------- */ --lang-ts: #3178c6; --lang-go: #00add8; --lang-rust: #e0723a; --lang-svelte: #ff3e00; --lang-py: #3572a5; --lang-js: #f1e05a; --lang-zig: #f7a41d; /* ---- Radii --------------------------------------------------------- */ --r-xs: 4px; --r-sm: 6px; --r-md: 8px; --r-lg: 14px; --r-xl: 16px; --r-xxl: 24px; --r-pill: 9999px; /* ---- Spacing (4px base) ------------------------------------------- */ --s-xxs: 4px; --s-xs: 8px; --s-sm: 12px; --s-md: 16px; --s-lg: 24px; --s-xl: 32px; --s-xxl: 48px; --s-section: 96px; /* ---- Type families ------------------------------------------------- */ --font-sans: "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif; --font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace; /* ---- Layout -------------------------------------------------------- */ --nav-h: 56px; --container: 1100px; /* narrower block → tighter cards (less name↔star gap) */ --content-shift: 80px; /* nudge content right (whole block) to clear the globe */ } /* ---- Reset ---------------------------------------------------------- */ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } html { -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; } body { background: var(--canvas); color: var(--ink); font-family: var(--font-sans); font-size: 16px; line-height: 1.5; letter-spacing: -0.05px; font-weight: 400; } a { color: inherit; text-decoration: none; } button { font-family: inherit; cursor: pointer; border: none; background: none; color: inherit; } input { font-family: inherit; } ::selection { background: var(--accent-tint); } /* Custom scrollbars — keep the dark frame clean */ * { scrollbar-width: thin; scrollbar-color: var(--hairline-strong) transparent; } *::-webkit-scrollbar { width: 8px; height: 8px; } *::-webkit-scrollbar-thumb { background: var(--hairline-strong); border-radius: var(--r-pill); } /* ============================================================================ Cursor glow — large faint radial light that trails the pointer ========================================================================== */ .cursor-glow { position: fixed; top: 0; left: 0; width: 140px; height: 140px; border-radius: 50%; pointer-events: none; z-index: 40; /* above content (visible on boxes), below the sticky nav (z 50) */ opacity: 0; transition: opacity 0.6s ease; will-change: transform; /* Gradual, gaussian-like falloff all the way to the edge — no hard ring, so it stays soft even over the flat box surfaces. */ background: radial-gradient( circle, rgba(255, 255, 255, 0.055) 0%, rgba(255, 255, 255, 0.032) 20%, rgba(255, 255, 255, 0.014) 45%, rgba(255, 255, 255, 0.004) 70%, rgba(255, 255, 255, 0) 100% ); } /* ============================================================================ Background globe — subtle, slowly spinning, peeking from the left edge ========================================================================== */ .globe { display: none; /* shown only on wide screens (see min-width media query) */ position: fixed; left: -190px; top: 50%; transform: translateY(-50%); width: 560px; height: 560px; z-index: 0; /* behind content (which is lifted to z 1) */ pointer-events: none; opacity: 0; animation: globe-in 1.6s ease 0.3s forwards; } .globe__canvas { display: block; width: 560px; height: 560px; } @keyframes globe-in { to { opacity: 0.5; } } /* ============================================================================ Top nav ========================================================================== */ .topnav { position: sticky; top: 0; z-index: 50; height: var(--nav-h); background: rgba(20, 21, 25, 0.82); /* subtly lighter than canvas, no divider */ backdrop-filter: blur(12px); } .topnav__inner { max-width: var(--container); height: 100%; margin: 0 auto; padding: 0 var(--s-lg); display: flex; align-items: center; gap: var(--s-md); } .brand { display: flex; align-items: center; gap: var(--s-xs); flex-shrink: 0; } .brand__logo { display: grid; place-items: center; color: var(--ink); } .brand__name { font-size: 17px; font-weight: 600; letter-spacing: -0.4px; color: var(--ink); } .badge { font-size: 11px; font-weight: 500; line-height: 1.2; padding: 2px 8px; border-radius: var(--r-pill); background: var(--surface-2); color: var(--ink-muted); border: 1px solid var(--hairline); letter-spacing: 0.2px; } .search { flex: 1; max-width: 520px; margin: 0 auto; display: flex; align-items: center; gap: var(--s-xs); height: 36px; padding: 0 var(--s-sm); background: var(--surface-1); border: 1px solid var(--hairline); border-radius: var(--r-md); color: var(--ink-subtle); transition: border-color 0.15s ease, background 0.15s ease; } .search:focus-within { border-color: var(--hairline-strong); background: var(--surface-2); } .search input { flex: 1; border: none; background: none; outline: none; color: var(--ink); font-size: 14px; } .search input::placeholder { color: var(--ink-subtle); } .kbd { font-family: var(--font-mono); font-size: 11px; color: var(--ink-subtle); padding: 1px 6px; border: 1px solid var(--hairline); border-radius: var(--r-xs); background: var(--canvas); } .topnav__right { display: flex; align-items: center; gap: var(--s-sm); flex-shrink: 0; } /* Create button: no perimeter outline */ .topnav__right .btn--secondary, .topnav__right .btn--secondary:hover { border-color: transparent; } .user-menu { position: relative; } .user { display: flex; align-items: center; gap: var(--s-xs); padding: 4px 10px 4px 4px; border-radius: var(--r-pill); border: 1px solid transparent; background: none; font: inherit; color: inherit; cursor: pointer; transition: border-color 0.15s ease, background 0.15s ease; } .user:hover { background: var(--surface-1); border-color: var(--hairline); } .user__handle { font-size: 13px; color: var(--ink-muted); } /* Account info card — popover anchored to the user chip. */ .user-card { position: absolute; top: calc(100% + 8px); right: 0; z-index: 50; width: 260px; display: flex; flex-direction: column; gap: var(--s-sm); padding: var(--s-md); background: var(--surface-1); border: 1px solid var(--hairline); border-radius: var(--r-lg); box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45); } .user-card__head { display: flex; align-items: center; gap: var(--s-sm); } .user-card__id { display: flex; flex-direction: column; gap: 2px; min-width: 0; } .user-card__handle { font-size: 14px; font-weight: 600; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .user-card__did { font-family: var(--font-mono); font-size: 11px; color: var(--ink-subtle); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .user-card__link { width: 100%; } /* ============================================================================ Buttons ========================================================================== */ .btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; font-size: 14px; font-weight: 500; line-height: 1.2; letter-spacing: 0; padding: 8px 14px; border-radius: var(--r-md); min-height: 36px; white-space: nowrap; transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.05s ease; } .btn:active { transform: translateY(0.5px); } .btn:focus-visible { outline: 2px solid color-mix(in srgb, var(--accent-focus) 50%, transparent); outline-offset: 2px; } .btn--primary { background: var(--accent); color: var(--on-accent); font-weight: 600; } .btn--primary:hover { background: var(--accent-hover); } .btn--primary:active { background: var(--accent-pressed); } .btn--secondary { background: var(--surface-1); color: var(--ink); border: 1px solid var(--hairline); } .btn--secondary:hover { background: var(--surface-2); border-color: var(--hairline-strong); } .btn--ghost { background: transparent; color: var(--ink-muted); } .btn--ghost:hover { background: var(--surface-1); color: var(--ink); } .btn--icon { min-height: 36px; width: 36px; padding: 0; border-radius: var(--r-md); color: var(--ink-subtle); } .btn--icon:hover { background: var(--surface-1); color: var(--ink); } /* Top-bar bookmark (saved posts). Carries a small count badge; lights up teal when the Saved page is the active view. */ .btn--bookmark { position: relative; } .btn--bookmark.is-active { color: var(--accent); background: var(--accent-tint); } .btn--bookmark__count { position: absolute; top: -3px; right: -3px; min-width: 16px; height: 16px; padding: 0 4px; display: grid; place-items: center; font-size: 10px; font-weight: 600; line-height: 1; color: var(--on-accent); background: var(--accent); border-radius: var(--r-pill); border: 2px solid var(--canvas); } .btn--sm { min-height: 30px; padding: 5px 11px; font-size: 13px; } /* GitTok entry button — teal like primary, but base weight so it matches Create's size. The play icon is filled (currentColor = dark ink-on-teal). */ .btn--feed { background: var(--accent); color: var(--on-accent); } .btn--feed:hover { background: var(--accent-hover); } /* Optically center the label with the play triangle */ .btn--feed__label { position: relative; top: 1px; } /* ============================================================================ Layout — 3-column dashboard ========================================================================== */ .layout { position: relative; z-index: 1; /* sits above the background globe */ max-width: var(--container); margin: 0 auto; padding: var(--s-xl) var(--s-lg) var(--s-section); display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: var(--s-lg); align-items: start; } .col { display: flex; flex-direction: column; gap: var(--s-lg); } .col--right { position: sticky; top: calc(var(--nav-h) + var(--s-xl)); /* Own scroll region: pinned under the nav, scrolls independently of the center column when its content is taller than the viewport. */ max-height: calc(100vh - var(--nav-h) - var(--s-xl) - var(--s-lg)); overflow-y: auto; /* room so the thin scrollbar doesn't sit on the panel border */ padding-right: 4px; margin-right: -4px; } /* ============================================================================ Panel (the lifted surface-1 card) + the white top-edge highlight ========================================================================== */ .panel { position: relative; background: var(--surface-1); border: 1px solid var(--edge-dark); border-radius: var(--r-lg); transition: border-color 0.2s ease, box-shadow 0.2s ease; } .panel:hover { box-shadow: var(--glow-hover); } .panel__head { display: flex; align-items: center; justify-content: space-between; padding: var(--s-md) var(--s-lg); border-bottom: 1px solid var(--hairline); } .panel__title { display: flex; align-items: center; gap: var(--s-xs); font-size: 14px; font-weight: 600; letter-spacing: -0.1px; color: var(--ink); } .panel__title svg { color: var(--ink-subtle); } .panel__action { display: inline-flex; align-items: center; gap: 4px; font-size: 13px; color: var(--ink-subtle); transition: color 0.15s ease; } .panel__action:hover { color: var(--accent); } .panel__body { padding: var(--s-sm) var(--s-xs); } /* Empty state inside a panel */ .empty { display: flex; flex-direction: column; align-items: center; gap: var(--s-xs); padding: var(--s-xl) var(--s-md); text-align: center; color: var(--ink-subtle); } .empty svg { color: var(--ink-tertiary); } .empty__title { font-size: 14px; color: var(--ink-muted); } /* ============================================================================ List rows (notifications + recents) ========================================================================== */ .row { display: flex; align-items: flex-start; gap: var(--s-sm); padding: var(--s-sm); border-radius: var(--r-md); transition: background 0.15s ease; } .row:hover { background: var(--surface-2); } .row__body { min-width: 0; flex: 1; } .row__text { font-size: 13px; line-height: 1.45; color: var(--ink-muted); } .row__text strong { color: var(--ink); font-weight: 600; } .row__time { font-size: 12px; color: var(--ink-tertiary); margin-top: 2px; } .row__icon { display: grid; place-items: center; width: 28px; height: 28px; flex-shrink: 0; border-radius: var(--r-sm); background: var(--surface-2); color: var(--ink-subtle); } .row__icon--star { color: var(--lang-js); } .row__icon--pr { color: var(--accent); } .row__icon--follow { color: var(--accent); } .row__icon--issue { color: var(--lang-go); } .recent { display: flex; align-items: center; gap: var(--s-sm); padding: var(--s-xs) var(--s-sm); border-radius: var(--r-md); transition: background 0.15s ease; } .recent:hover { background: var(--surface-2); } .recent__name { font-size: 13px; color: var(--ink-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .recent__name b { color: var(--ink); font-weight: 500; } .recent__time { margin-left: auto; font-size: 12px; color: var(--ink-tertiary); flex-shrink: 0; } /* ============================================================================ Avatars ========================================================================== */ .avatar { display: grid; place-items: center; flex-shrink: 0; border-radius: var(--r-pill); color: #fff; font-weight: 600; letter-spacing: -0.2px; overflow: hidden; } .avatar--sm { width: 28px; height: 28px; font-size: 11px; } .avatar--md { width: 36px; height: 36px; font-size: 13px; } .avatar--lg { width: 44px; height: 44px; font-size: 15px; } /* ============================================================================ Center column — Recommendations ========================================================================== */ .center-head { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--s-md); flex-wrap: wrap; margin-bottom: var(--s-xs); } .center-head__eyebrow { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 500; letter-spacing: 0.4px; text-transform: uppercase; color: var(--accent); margin-bottom: var(--s-xs); } .center-head h1 { font-size: 28px; font-weight: 600; line-height: 1.2; letter-spacing: -0.6px; color: var(--ink); } .center-head p { font-size: 14px; color: var(--ink-subtle); margin-top: 6px; max-width: 46ch; } /* Pill toggle (For you / Trending / New) */ .toggle { display: inline-flex; padding: 3px; gap: 2px; background: var(--surface-1); border-radius: var(--r-pill); } .toggle__btn { font-size: 13px; font-weight: 500; color: var(--ink-subtle); padding: 6px 14px; min-height: 32px; border-radius: var(--r-pill); transition: color 0.15s ease, background 0.15s ease; } .toggle__btn:hover { color: var(--ink-muted); } .toggle__btn--active { background: var(--surface-3); color: var(--ink); } /* Heading dropdown — "For you ▾" view selector */ .headsel { position: relative; } .headsel__btn { display: inline-flex; align-items: center; gap: 6px; padding: 0; background: none; border: none; cursor: pointer; font-size: 28px; font-weight: 600; line-height: 1.2; letter-spacing: -0.6px; color: var(--ink); } .headsel__chev { margin-top: 3px; color: var(--ink-subtle); transition: transform 0.2s ease, color 0.15s ease; } .headsel__btn:hover .headsel__chev { color: var(--ink); } .headsel__chev.is-open { transform: rotate(180deg); } .headsel__menu { position: absolute; top: calc(100% + 8px); left: 0; z-index: 30; min-width: 220px; display: flex; flex-direction: column; gap: 2px; padding: 6px; background: var(--surface-3); border: 1px solid var(--hairline); border-radius: var(--r-lg); box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45); animation: headsel-in 0.14s ease; } @keyframes headsel-in { from { opacity: 0; transform: translateY(-4px); } } .headsel__item { display: flex; align-items: center; gap: var(--s-sm); padding: 9px 12px; font-size: 14px; font-weight: 500; text-align: left; color: var(--ink-muted); background: none; border: none; border-radius: var(--r-md); cursor: pointer; transition: background 0.15s ease, color 0.15s ease; } .headsel__item svg { color: var(--ink-subtle); } .headsel__item:hover { background: var(--surface-2); color: var(--ink); } .headsel__item.is-active, .headsel__item.is-active svg { color: var(--accent); } .rec-list { display: flex; flex-direction: column; gap: var(--s-md); margin-top: var(--s-md); } /* Recommendation card */ .rec { position: relative; background: var(--surface-1); border: 1px solid var(--edge-dark); border-radius: var(--r-lg); padding: var(--s-lg); transition: background 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease; } .rec:hover { box-shadow: var(--glow-hover); transform: translateY(-1px); } .rec__reason { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 500; color: var(--on-accent); background: var(--accent); border-radius: var(--r-pill); padding: 3px 10px; margin-bottom: var(--s-md); } .rec__head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s-md); } .rec__repo { display: flex; align-items: center; gap: var(--s-xs); min-width: 0; } .rec__repo svg { color: var(--ink-subtle); flex-shrink: 0; } .rec__name { font-size: 17px; font-weight: 600; letter-spacing: -0.2px; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .rec__name .owner { color: var(--ink-subtle); font-weight: 500; } .rec__name:hover .repo { color: var(--accent); } /* Star split-button */ .star { display: inline-flex; align-items: stretch; flex-shrink: 0; border: 1px solid var(--hairline); border-radius: var(--r-md); overflow: hidden; background: var(--surface-1); transition: border-color 0.15s ease; } .rec:hover .star { border-color: var(--hairline-strong); } .star__btn { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 500; color: var(--ink-muted); padding: 6px 11px; transition: color 0.15s ease, background 0.15s ease; } .star__btn:hover { background: var(--surface-3); color: var(--ink); } .star__btn.is-on { color: var(--accent); } .star__count { display: inline-flex; align-items: center; padding: 6px 11px; font-size: 13px; font-weight: 500; color: var(--ink); background: var(--surface-2); border-left: 1px solid var(--hairline); min-width: 38px; justify-content: center; } .rec__desc { font-size: 14px; line-height: 1.5; color: var(--ink-muted); margin-top: var(--s-sm); max-width: 64ch; } .rec__meta { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-md); margin-top: var(--s-md); } .meta-item { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; color: var(--ink-subtle); } .meta-item svg { color: var(--ink-tertiary); } .lang { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--ink-subtle); } .lang__dot { width: 9px; height: 9px; border-radius: var(--r-pill); flex-shrink: 0; } .tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--s-md); } .tag { font-size: 12px; color: var(--ink-subtle); background: var(--surface-2); border: 1px solid var(--hairline); border-radius: var(--r-sm); padding: 2px 8px; transition: color 0.15s ease, border-color 0.15s ease; } .tag:hover { color: var(--ink-muted); border-color: var(--hairline-strong); } /* ============================================================================ Right column — Suggested profiles ========================================================================== */ .profile { display: flex; flex-direction: column; gap: var(--s-sm); padding: var(--s-md); transition: background 0.15s ease; } .profile:hover { background: var(--surface-2); } .profile + .profile { border-top: 1px solid var(--hairline-tertiary); } .profile__top { display: flex; align-items: center; gap: var(--s-sm); } .profile__id { min-width: 0; flex: 1; } .profile__avatar { flex-shrink: 0; display: inline-flex; line-height: 0; border-radius: var(--r-pill); transition: opacity 0.15s ease; } .profile__avatar:hover { opacity: 0.85; } .profile__handle { display: block; font-size: 14px; font-weight: 600; color: var(--ink); text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: color 0.15s ease; } .profile__handle:hover { color: var(--accent); text-decoration: underline; } .profile__did { margin-top: 1px; font-family: var(--font-mono, ui-monospace, "SF Mono", monospace); font-size: 11px; color: var(--ink-subtle); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .profile__active { display: inline-flex; align-items: center; gap: 4px; margin-top: 3px; font-size: 11px; color: var(--ink-subtle); } .profile__active svg { color: var(--ink-tertiary); flex-shrink: 0; } .profile__stack { display: flex; flex-wrap: wrap; gap: 6px; } .profile__stats { display: flex; flex-wrap: wrap; gap: var(--s-md); font-size: 12px; color: var(--ink-subtle); } .profile__stats b { color: var(--ink-muted); font-weight: 600; } /* Load more — full-width row under the suggested profiles */ .profile__more { display: flex; align-items: center; justify-content: center; gap: 6px; width: 100%; margin-top: var(--s-xs); padding: var(--s-sm); font-size: 13px; font-weight: 500; color: var(--ink-muted); background: transparent; border: none; border-top: 1px solid var(--hairline-tertiary); cursor: pointer; transition: background 0.15s ease, color 0.15s ease; } .profile__more:hover:not(:disabled) { background: var(--surface-2); color: var(--ink); } .profile__more:disabled { cursor: default; color: var(--ink-subtle); } /* Inline message / retry for empty + error states */ .panel__msg { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-xs); padding: var(--s-md); font-size: 13px; color: var(--ink-subtle); } .panel__retry { font-size: 13px; font-weight: 500; color: var(--accent); background: none; border: none; cursor: pointer; } .panel__retry:hover { color: var(--accent-hover); } /* Skeleton placeholders while a query is running */ .skel { display: block; background: linear-gradient( 90deg, var(--surface-2) 0%, var(--surface-3) 50%, var(--surface-2) 100% ); background-size: 200% 100%; animation: skel-shimmer 1.2s ease-in-out infinite; border-radius: var(--r-sm); } .skel--avatar { width: 36px; height: 36px; border-radius: 50%; flex: none; } .skel--line { height: 11px; margin: 5px 0; } .skel--sm { height: 8px; } @keyframes skel-shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } } .auth__spinner--ghost { border-color: color-mix(in srgb, var(--ink-subtle) 35%, transparent); border-top-color: var(--ink-muted); } @media (prefers-reduced-motion: reduce) { .skel { animation: none; } } /* ============================================================================ Hero landing / login page — centered, no card, floating logo ========================================================================== */ .hero { position: relative; z-index: 1; min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; /* Sit the block a touch above dead-center ("mid/top") */ padding: 12vh var(--s-lg) 18vh; } .hero__inner { width: 100%; max-width: 640px; display: flex; flex-direction: column; align-items: center; animation: hero-in 0.7s cubic-bezier(0.16, 1, 0.3, 1) both; } @keyframes hero-in { from { opacity: 0; transform: translateY(14px); } } /* Large floating mark with a soft teal glow behind it */ .hero__logo { position: relative; display: grid; place-items: center; color: var(--accent); margin-bottom: var(--s-xl); animation: hero-float 6s ease-in-out infinite; } .hero__logo::before { content: ""; position: absolute; inset: -60% -60%; background: radial-gradient( circle, rgba(31, 184, 166, 0.22) 0%, rgba(31, 184, 166, 0.08) 35%, rgba(31, 184, 166, 0) 70% ); z-index: -1; pointer-events: none; } @keyframes hero-float { 50% { transform: translateY(-8px); } } .hero__headline { font-size: clamp(26px, 4vw, 38px); font-weight: 600; line-height: 1.15; letter-spacing: -0.8px; color: var(--ink); max-width: 22ch; } .hero__sub { font-size: clamp(15px, 1.6vw, 17px); line-height: 1.6; color: var(--ink-subtle); margin-top: var(--s-md); max-width: 52ch; } .hero__form { width: 100%; max-width: 560px; display: flex; flex-direction: column; align-items: center; gap: var(--s-sm); margin-top: var(--s-xl); } .hero__field { width: 100%; display: flex; gap: var(--s-xs); padding: 6px; background: var(--surface-1); border: 1px solid var(--hairline); border-radius: var(--r-lg); transition: border-color 0.2s ease, box-shadow 0.2s ease; } .hero__field:focus-within { border-color: var(--accent-tint-border); box-shadow: 0 0 0 4px var(--accent-tint); } .hero__field[data-error="true"] { border-color: color-mix(in srgb, #e5484d 55%, var(--hairline)); } .hero__input { flex: 1; min-width: 0; height: 48px; padding: 0 var(--s-md); font-size: 15px; text-align: left; color: var(--ink); background: transparent; border: none; outline: none; } .hero__input::placeholder { color: var(--ink-tertiary); } .hero__submit { height: 48px; flex-shrink: 0; padding: 0 var(--s-lg); border-radius: var(--r-md); } .hero__hint { font-size: 13px; color: var(--ink-tertiary); } .hero__error { font-size: 13px; line-height: 1.5; color: #f0888c; } @media (prefers-reduced-motion: reduce) { .hero__inner, .hero__logo { animation: none; } } /* Button spinner for the connecting state */ .auth__spinner { width: 14px; height: 14px; border-radius: 50%; border: 2px solid color-mix(in srgb, var(--on-accent) 35%, transparent); border-top-color: var(--on-accent); animation: auth-spin 0.6s linear infinite; } @keyframes auth-spin { to { transform: rotate(360deg); } } /* ============================================================================ Responsive ========================================================================== */ /* Wide screens: reveal the globe and shift the whole content block right. The min() cap keeps it from ever overflowing the viewport on narrower widths — it gracefully hugs the right edge instead. */ @media (min-width: 1280px) { .globe { display: block; } .topnav__inner, .layout { margin-left: min( calc((100% - var(--container)) / 2 + var(--content-shift)), calc(100% - var(--container) - var(--s-lg)) ); margin-right: var(--s-lg); } } @media (max-width: 1024px) { .layout { grid-template-columns: minmax(0, 1fr); } .col--right { display: none; } } @media (max-width: 820px) { .layout { padding: var(--s-lg) var(--s-md) var(--s-xxl); } .search { max-width: none; } .center-head h1 { font-size: 24px; } } @media (max-width: 560px) { .topnav__inner { padding: 0 var(--s-md); } .user__handle, .kbd { display: none; } .hero { padding: 10vh var(--s-md) 14vh; } .hero__field { flex-direction: column; } .hero__submit { width: 100%; } } /* ============================================================================ GitTok — vertical snap feed of projects (TikTok / Reels / Shorts style) ========================================================================== */ .feed { position: relative; height: 100dvh; background: var(--canvas); overflow: hidden; } .feed__bar { position: absolute; top: 0; left: 0; right: 0; z-index: 5; height: var(--nav-h); display: flex; align-items: center; justify-content: space-between; padding: 0 var(--s-lg); background: linear-gradient(to bottom, rgba(1, 1, 2, 0.75), rgba(1, 1, 2, 0)); pointer-events: none; } .feed__bar > * { pointer-events: auto; } .feed__back { display: inline-flex; align-items: center; gap: 6px; font-size: 14px; font-weight: 500; color: var(--ink-muted); padding: 8px 12px; border-radius: var(--r-md); transition: background 0.15s ease, color 0.15s ease; } .feed__back:hover { background: var(--surface-2); color: var(--ink); } .feed__title { font-size: 15px; font-weight: 600; letter-spacing: -0.2px; color: var(--ink); } .feed__hint { font-size: 12px; color: var(--ink-subtle); } .feed__scroll { height: 100%; overflow-y: auto; scroll-snap-type: y mandatory; scrollbar-width: none; } .feed__scroll::-webkit-scrollbar { display: none; } .reel { height: 100dvh; scroll-snap-align: start; scroll-snap-stop: always; display: flex; align-items: center; justify-content: center; padding: var(--s-md); } .reel__stage { display: flex; align-items: flex-end; gap: var(--s-md); height: min(86dvh, 760px); } .reel__card { position: relative; width: min(440px, 86vw); height: 100%; border-radius: var(--r-xl); border: 1px solid var(--edge-dark); overflow: hidden; display: flex; flex-direction: column; justify-content: flex-end; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4); } .reel__bg { position: absolute; inset: 0; z-index: 0; } .reel__inner { position: relative; z-index: 1; display: flex; flex-direction: column; gap: var(--s-sm); padding: var(--s-lg); background: linear-gradient(to top, rgba(1, 1, 2, 0.92) 35%, rgba(1, 1, 2, 0)); } .reel__reason { align-self: flex-start; font-size: 12px; font-weight: 500; color: var(--on-accent); background: var(--accent); border-radius: var(--r-pill); padding: 3px 10px; } .reel__name { font-size: 19px; font-weight: 600; line-height: 1.25; letter-spacing: -0.3px; color: var(--ink); /* Issue titles can be long — clamp to 3 lines so the card never blows out. */ display: -webkit-box; -webkit-line-clamp: 3; line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; } .reel__name--link { text-decoration: none; transition: color 0.15s ease; } .reel__name--link:hover { color: var(--accent); } .reel__repo { display: inline-flex; align-items: center; gap: 5px; align-self: flex-start; max-width: 100%; font-size: 12.5px; color: var(--ink-subtle); text-decoration: none; transition: color 0.15s ease; } .reel__repo:hover { color: var(--ink); } .reel__repo-owner { color: var(--ink-subtle); } .reel__repo-name { color: var(--ink-muted); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .reel__repo svg:last-child { opacity: 0.6; flex: none; } .reel__owner { color: var(--ink-subtle); font-weight: 500; } .reel__desc { font-size: 14px; line-height: 1.5; color: var(--ink-muted); } .reel__metarow { display: flex; flex-wrap: wrap; gap: var(--s-md); margin-top: 2px; } .reel__tags { display: flex; flex-wrap: wrap; gap: 6px; } .reel__creator { display: flex; align-items: center; gap: var(--s-sm); margin-top: var(--s-xs); padding-top: var(--s-sm); } .reel__creator-id { flex: 1; min-width: 0; } .reel__creator-avatar { flex-shrink: 0; display: inline-flex; line-height: 0; border-radius: var(--r-pill); transition: opacity 0.15s ease; } .reel__creator-avatar:hover { opacity: 0.85; } .reel__creator-handle { display: block; font-size: 14px; font-weight: 600; color: var(--ink); text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .reel__creator-handle:hover { color: var(--accent); text-decoration: underline; } .reel__creator-sub { font-size: 12px; color: var(--ink-subtle); } /* Follow button in the reel: no visible border line */ .reel__creator .btn--secondary, .reel__creator .btn--secondary:hover { border-color: transparent; } .reel__rail { display: flex; flex-direction: column; justify-content: flex-end; gap: var(--s-md); height: 100%; padding-bottom: var(--s-lg); } .reel-action { display: flex; flex-direction: column; align-items: center; gap: 6px; } .reel-action__btn { width: 48px; height: 48px; border-radius: var(--r-pill); display: grid; place-items: center; color: var(--ink); background: var(--surface-2); border: none; transition: background 0.15s ease, color 0.15s ease, transform 0.1s ease; } .reel-action__btn:hover { background: var(--surface-3); } .reel-action__btn:active { transform: scale(0.92); } .reel-action__btn.is-liked { color: var(--accent); } /* Satisfying double-thump heartbeat on like */ .reel-action__btn.is-liked svg { animation: heart-beat 0.6s cubic-bezier(0.22, 1, 0.36, 1); transform-origin: center; } @keyframes heart-beat { 0% { transform: scale(1); } 18% { transform: scale(1.4); } 32% { transform: scale(0.92); } 52% { transform: scale(1.22); } 72% { transform: scale(0.97); } 100% { transform: scale(1); } } @media (prefers-reduced-motion: reduce) { .reel-action__btn.is-liked svg { animation: none; } } .reel-action__count { font-size: 12px; color: var(--ink-muted); min-width: 44px; text-align: center; } .reel-action__btn.is-saved { color: var(--accent); } /* ---- The placeholder "image": a faux GitHub repo code snippet ------------- */ /* Same placeholder on every card until the backend attaches a real preview. Sits full-bleed behind the .reel__inner text scrim. */ .reel__snippet { position: absolute; inset: 0; z-index: 0; display: flex; flex-direction: column; background: radial-gradient( 120% 70% at 50% 0%, rgba(31, 184, 166, 0.1), transparent 60% ), var(--surface-1); overflow: hidden; } /* Bottom-up black scrim over the README peek: the code stays fully visible across the top, then fades to solid black toward the bottom so the issue text overlaid by .reel__inner reads cleanly over it. Scoped to the snippet (not the whole card) so the centered "Code preview unavailable" fallback — lifted above this with its own z-index below — is never dimmed. pointer-events:none keeps the fallback's "Open in Tangled" link clickable. */ .reel__snippet::after { content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none; background: linear-gradient( to top, rgba(1, 1, 2, 0.98) 0%, rgba(1, 1, 2, 0.97) 45%, rgba(1, 1, 2, 0.85) 62%, rgba(1, 1, 2, 0.45) 80%, rgba(1, 1, 2, 0) 96% ); } .reel__snippet-chrome { display: flex; align-items: center; gap: var(--s-sm); padding: 10px 14px; border-bottom: 1px solid var(--hairline); background: var(--surface-2); } .reel__snippet-dots { display: inline-flex; gap: 6px; } .reel__snippet-dots i { width: 10px; height: 10px; border-radius: var(--r-pill); background: var(--surface-4); } .reel__snippet-file { font-family: var(--font-mono); font-size: 12px; color: var(--ink-subtle); } .reel__snippet-body { display: flex; flex-direction: column; gap: 9px; padding: var(--s-md) var(--s-md) 0; } .snip-line { display: flex; align-items: center; gap: 12px; } .snip-ln { width: 18px; flex-shrink: 0; text-align: right; font-family: var(--font-mono); font-size: 11px; color: var(--ink-tertiary); opacity: 0.6; } .snip-bar { height: 8px; border-radius: var(--r-xs); background: var(--surface-3); } .snip-bar--kw { background: color-mix(in srgb, var(--accent) 35%, var(--surface-3)); } .snip-bar--fn { background: color-mix(in srgb, var(--lang-ts) 38%, var(--surface-3)); } .snip-bar--str { background: color-mix(in srgb, var(--lang-zig) 30%, var(--surface-3)); } .reel__snippet-note { position: absolute; top: 32%; left: 0; right: 0; text-align: center; font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.4px; color: var(--ink-tertiary); opacity: 0.7; } /* ---- Live README peek: skeleton rows, real code, and the fallback --------- */ /* A row is shared by the loading skeleton (.skel bar) and a real code line. */ .snip-row { display: flex; align-items: baseline; gap: 12px; } .reel__snippet-body--code { gap: 2px; padding-bottom: var(--s-md); overflow: hidden; mask-image: linear-gradient(to bottom, #000 70%, transparent); -webkit-mask-image: linear-gradient(to bottom, #000 70%, transparent); } .snip-code { font-family: var(--font-mono); font-size: 11.5px; line-height: 1.5; color: var(--ink-muted); white-space: pre; overflow: hidden; text-overflow: ellipsis; } .snip-more { padding-left: 30px; font-family: var(--font-mono); color: var(--ink-tertiary); opacity: 0.7; } .reel__snippet-fallback { position: absolute; inset: 0; /* Above the snippet's bottom-up scrim (z 1) so the fallback stays crisp. */ z-index: 2; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; color: var(--ink-tertiary); } .reel__snippet-fallback p { font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.3px; } .reel__snippet-fallback a { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--accent); text-decoration: none; } .reel__snippet-fallback a:hover { text-decoration: underline; } /* ---- Issue-specific text bits -------------------------------------------- */ .issue-state { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; color: var(--success); text-transform: capitalize; } .issue-state svg { color: var(--success); } .issue-badge { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; font-weight: 500; color: var(--accent); background: var(--accent-tint); border: 1px solid var(--accent-tint-border); border-radius: var(--r-pill); padding: 2px 9px; } /* The shared lang/topic tags — the "why you're seeing this" overlap. */ .tag--match { color: var(--accent); background: var(--accent-tint); border-color: var(--accent-tint-border); } .reel__stats { display: flex; flex-wrap: wrap; gap: var(--s-md); margin-top: 2px; } /* ---- Feed bar: clear history + actions ----------------------------------- */ .feed__actions { display: inline-flex; align-items: center; gap: var(--s-sm); } .feed__clear { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 500; color: var(--ink-muted); background: var(--surface-2); border: 1px solid var(--hairline); border-radius: var(--r-md); padding: 7px 12px; transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease; } .feed__clear:hover:not(:disabled) { background: var(--surface-3); color: var(--ink); border-color: var(--hairline-strong); } .feed__clear:disabled { opacity: 0.45; cursor: not-allowed; } /* ---- Status reels: loading / error / end-of-feed ------------------------- */ .reel__status { display: flex; flex-direction: column; align-items: center; gap: var(--s-md); text-align: center; padding: var(--s-lg); } .reel__status-text { font-size: 15px; color: var(--ink-muted); max-width: 34ch; line-height: 1.5; } .reel__spinner { width: 30px; height: 30px; border-radius: var(--r-pill); border: 3px solid var(--surface-3); border-top-color: var(--accent); animation: reel-spin 0.8s linear infinite; } @keyframes reel-spin { to { transform: rotate(360deg); } } @media (prefers-reduced-motion: reduce) { .reel__spinner { animation: none; } } @media (max-width: 560px) { .reel__stage { height: min(82dvh, 680px); } .reel__rail { gap: var(--s-sm); padding-bottom: var(--s-md); } .reel-action__btn { width: 42px; height: 42px; } } /* ============================================================================ Feed selector — tab bar with built-in + custom feeds + "+" builder ========================================================================== */ .feed-tabs { flex-wrap: wrap; max-width: 100%; } /* Thin divider between built-in and custom feed tabs. */ .feed-tabs__div { width: 1px; align-self: stretch; margin: 4px 4px; background: var(--hairline-strong); } /* A custom feed tab = pick button + delete affordance in one pill. */ .feed-tabs__custom { display: inline-flex; align-items: center; gap: 2px; padding: 0 4px 0 0; } .feed-tabs__pick { font: inherit; color: inherit; padding: 6px 4px 6px 14px; } .feed-tabs__del { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; border-radius: var(--r-pill); color: var(--ink-tertiary); transition: color 0.15s ease, background 0.15s ease; } .feed-tabs__del:hover { color: var(--ink); background: var(--surface-4); } .feed-tabs__add { display: inline-flex; align-items: center; justify-content: center; min-width: 32px; color: var(--ink-subtle); } .feed-tabs__add:hover { color: var(--accent); } /* ============================================================================ Feed builder modal ========================================================================== */ .fb-overlay { position: fixed; inset: 0; z-index: 50; display: flex; align-items: flex-start; justify-content: center; padding: 8vh var(--s-md) var(--s-md); background: rgba(1, 1, 2, 0.66); backdrop-filter: blur(3px); overflow-y: auto; } .fb { width: 100%; max-width: 560px; padding: 0; } .fb__head { display: flex; align-items: center; justify-content: space-between; padding: var(--s-md) var(--s-lg); border-bottom: 1px solid var(--hairline); } .fb__title { display: inline-flex; align-items: center; gap: 8px; font-size: 15px; font-weight: 600; color: var(--ink); } .fb__title svg { color: var(--accent); } .fb__body { display: flex; flex-direction: column; gap: var(--s-md); padding: var(--s-lg); } .fb__field { display: flex; flex-direction: column; gap: 8px; } .fb__label { font-size: 13px; font-weight: 500; color: var(--ink-subtle); } .fb__input { font: inherit; font-size: 14px; color: var(--ink); background: var(--surface-2); border: 1px solid var(--hairline); border-radius: var(--r-md); padding: 9px 12px; transition: border-color 0.15s ease; } .fb__input:focus-visible { outline: none; border-color: var(--accent-focus); } select.fb__input { cursor: pointer; } /* Selectable filter chip — reuses .tag, lights up teal when on. */ .fb__chip { cursor: pointer; } .fb__chip.is-on { color: var(--accent); background: var(--accent-tint); border-color: var(--accent-tint-border); } .fb__error { font-size: 13px; color: #ff6b6b; } .fb__actions { display: flex; justify-content: flex-end; gap: var(--s-sm); margin-top: var(--s-xs); } /* ============================================================================ Feed menu (headsel) — section labels, deletable rows, action items ========================================================================== */ .headsel__menu { min-width: 248px; max-height: 70vh; overflow-y: auto; } .headsel__label { padding: 8px 12px 4px; font-size: 11px; font-weight: 600; letter-spacing: 0.4px; text-transform: uppercase; color: var(--ink-tertiary); } .headsel__sep { height: 1px; margin: 6px 8px; background: var(--hairline); } /* A row with a pick button + a delete/unsubscribe affordance. */ .headsel__item--row { padding: 0; gap: 0; } .headsel__item--row.is-active .headsel__pick { color: var(--accent); } .headsel__item--row.is-active .headsel__pick svg { color: var(--accent); } .headsel__pick { flex: 1; display: inline-flex; align-items: center; gap: var(--s-sm); padding: 9px 8px 9px 12px; font: inherit; font-size: 14px; font-weight: 500; text-align: left; color: var(--ink-muted); border-radius: var(--r-md); } .headsel__pick svg { color: var(--ink-subtle); } .headsel__item--row:hover .headsel__pick { color: var(--ink); } .headsel__row-act { display: inline-flex; align-items: center; justify-content: center; width: 30px; align-self: stretch; color: var(--ink-tertiary); border-radius: var(--r-md); transition: color 0.15s ease, background 0.15s ease; } .headsel__row-act:hover { color: var(--ink); background: var(--surface-2); } .headsel__item--action { color: var(--accent); } .headsel__item--action svg { color: var(--accent); } /* ============================================================================ Login — stacked handle + app-password fields, full-width submit ========================================================================== */ .hero__submit--full { width: 100%; justify-content: center; margin-top: var(--s-xxs); } /* ============================================================================ Feed bar — built-in topic tabs + "More topics" dropdown + Generator button ========================================================================== */ .feedbar { display: flex; align-items: center; flex-wrap: wrap; justify-content: flex-end; gap: var(--s-xs); } .feedbar__btn { display: inline-flex; align-items: center; gap: 6px; height: 38px; padding: 0 14px; font-size: 13px; font-weight: 500; color: var(--ink-muted); background: var(--surface-1); border: 1px solid var(--hairline); border-radius: var(--r-pill); transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease; } .feedbar__btn:hover { color: var(--ink); border-color: var(--hairline-strong); } .feedbar__btn--accent { color: var(--accent); background: var(--accent-tint); border-color: var(--accent-tint-border); } .feedbar__btn--accent:hover { color: var(--accent-hover); border-color: var(--accent); } .feedbar__chev { color: var(--ink-subtle); transition: transform 0.2s ease; } .feedbar__chev.is-open { transform: rotate(180deg); } .feedbar__more { position: relative; } /* Anchor the shared dropdown to the right edge of the "More topics" button. */ .feedbar__menu { left: auto; right: 0; } .feedbar__empty { max-width: 240px; padding: 10px 12px; font-size: 13px; line-height: 1.5; color: var(--ink-subtle); } /* Top bar: "For you ▾" dropdown on the left, feed controls on the right. */ .center-head--bar { align-items: center; gap: var(--s-md); } /* ============================================================================ Inline generator panel — between the topic controls and the feed list ========================================================================== */ .genpanel { margin-top: var(--s-md); padding: var(--s-md) var(--s-lg); display: flex; flex-direction: column; gap: var(--s-sm); background: var(--surface-1); border: 1px solid var(--accent-tint-border); border-radius: var(--r-lg); } .genpanel__head { display: flex; align-items: center; gap: var(--s-sm); flex-wrap: wrap; } .genpanel__title { font-size: 15px; font-weight: 600; color: var(--ink); } .genpanel__hint { font-size: 12px; color: var(--ink-subtle); } .genpanel__head-actions { display: inline-flex; align-items: center; gap: var(--s-xs); margin-left: auto; } .genpanel__row { display: flex; flex-direction: column; gap: 6px; } .genpanel__label { font-size: 12px; font-weight: 500; letter-spacing: 0.2px; color: var(--ink-subtle); } .genpanel__select { max-width: 200px; } /* Name popup — the only modal in the generator flow (just the name field). */ .namepop { width: 100%; max-width: 380px; padding: var(--s-lg); display: flex; flex-direction: column; gap: var(--s-sm); } .namepop__title { font-size: 15px; font-weight: 600; color: var(--ink); } /* ============================================================================ Feed builder / add-feed dialog extras ========================================================================== */ .fb__inline { display: flex; gap: var(--s-sm); } .fb__inline .fb__input { flex: 1; } .fb__hint { font-size: 13px; color: var(--ink-subtle); } .fb__results { display: flex; flex-direction: column; gap: var(--s-xs); max-height: 220px; overflow-y: auto; } .fb__result { display: flex; align-items: center; justify-content: space-between; gap: var(--s-sm); padding: 10px 12px; background: var(--surface-2); border: 1px solid var(--hairline); border-radius: var(--r-md); } .fb__result-name { font-size: 14px; font-weight: 600; color: var(--ink); } .fb__result-sub { font-size: 12px; color: var(--ink-subtle); margin-top: 2px; } .fb__preview { display: flex; flex-direction: column; gap: 6px; max-height: 240px; overflow-y: auto; padding: var(--s-xs); background: var(--surface-2); border: 1px solid var(--hairline); border-radius: var(--r-md); } .fb__preview-empty { font-size: 13px; color: var(--ink-subtle); padding: var(--s-sm); } .fb__preview-card { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-sm); padding: 7px 10px; background: var(--surface-1); border: 1px solid var(--hairline-tertiary); border-radius: var(--r-sm); } .fb__preview-title { font-size: 13px; font-weight: 500; color: var(--ink-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .fb__preview-reason { flex-shrink: 0; font-size: 11px; color: var(--accent); } .fb__save { display: flex; flex-direction: column; gap: var(--s-sm); }