From a069c2fb2fba39038583c104f25a470b10bcc024 Mon Sep 17 00:00:00 2001 From: Cesar Alcazar Date: Tue, 20 Oct 2026 09:07:23 -0600 Subject: [PATCH 1/7] 99puxwol5: Delete legacy.css and move its last rules into the component stylesheets --- src/app/globals.css | 2 ++ src/app/layout.tsx | 1 - src/components/Composer.tsx | 2 +- src/components/SignInForm.tsx | 2 +- src/styles/buttons.css | 6 +++--- src/styles/composer.css | 3 +++ src/styles/layout.css | 3 +++ src/styles/legacy.css | 15 --------------- src/styles/post.css | 2 +- src/styles/signin.css | 2 +- 10 files changed, 15 insertions(+), 23 deletions(-) delete mode 100644 src/styles/legacy.css diff --git a/src/app/globals.css b/src/app/globals.css index bbc11b1..7a53f8c 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -91,6 +91,8 @@ @layer reset { *, *::before, *::after { box-sizing: border-box; } body { margin: 0; } + /* Form controls take the page font instead of the UA's 13.33px Arial. */ + button, input, textarea, select { font: inherit; } } @layer base { diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 1d69a50..d1d6c4a 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -16,7 +16,6 @@ import "../styles/trending.css"; import "../styles/search.css"; import "../styles/mobile.css"; import "../styles/sheet.css"; -import "../styles/legacy.css"; const manrope = Manrope({ subsets: ["latin"], diff --git a/src/components/Composer.tsx b/src/components/Composer.tsx index ba84a0b..4f71b45 100644 --- a/src/components/Composer.tsx +++ b/src/components/Composer.tsx @@ -210,7 +210,7 @@ export function Composer({ value, busy, error, file = null, onChange, onFile, on ) : null} {error ? ( -

Publishing the post failed. Your text is still here.

+

Publishing the post failed. Your text is still here.

) : null}
{onFile ? ( diff --git a/src/components/SignInForm.tsx b/src/components/SignInForm.tsx index d98d9d8..fdb040c 100644 --- a/src/components/SignInForm.tsx +++ b/src/components/SignInForm.tsx @@ -44,7 +44,7 @@ export function SignInForm({ onSignedIn }: { onSignedIn: (p: Person) => void })
{error && ( -

+

{error}

)} diff --git a/src/styles/buttons.css b/src/styles/buttons.css index 265e7a3..d62253f 100644 --- a/src/styles/buttons.css +++ b/src/styles/buttons.css @@ -2,8 +2,8 @@ * Button system (spec "Buttons", ADR 0001 sections 6 to 8). * Five styles plus the glossy crimson icon button, ported from the mockup's * recolored rules. Tokens only; white and black appear only on crimson faces. - * Every class sets margin, padding, font and color itself so the legacy - * `button` rules and any `button { color: inherit }` never leak in. + * Every class sets margin, padding, font and color itself so no global + * `button` rule, such as `button { color: inherit }`, can leak in. */ /* Shared base for every style. */ @@ -242,7 +242,7 @@ .btn-depth .btn-depth-icon svg { width: 20px; height: 20px; } .btn-depth .btn-depth-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; } .btn-depth .btn-depth-label { font-size: 15px; font-weight: 700; color: inherit; } -.btn-depth .btn-depth-sub { font-size: 12.5px; color: var(--ink-3); transition: color .3s; } +.btn-depth .btn-depth-sub { font-size: 12.5px; font-weight: 500; color: var(--ink-3); transition: color .3s; } .btn-depth:hover, .btn-depth:focus-visible { color: var(--on-accent); } .btn-depth:hover::before, diff --git a/src/styles/composer.css b/src/styles/composer.css index 88a533b..0028599 100644 --- a/src/styles/composer.css +++ b/src/styles/composer.css @@ -220,3 +220,6 @@ .composer-att, .composer-prog i { animation: none !important; } } + +/* Publish failure, above the toolbar. */ +.composer-error { margin: 0 0 4px; padding: 10px 12px; border: 1px solid var(--accent); border-radius: 8px; color: var(--danger); background: var(--accent-soft); font-size: 14px; } diff --git a/src/styles/layout.css b/src/styles/layout.css index d4933c7..a6c86e2 100644 --- a/src/styles/layout.css +++ b/src/styles/layout.css @@ -2,6 +2,9 @@ .app is the size container; .bento is its child, so container queries can style it. The page never scrolls: only the panels' own lists do. */ +/* Session check: one centered line while the session loads. */ +.center { min-height: 100vh; display: grid; place-items: center; padding: 16px; } + .app { container: app / inline-size; height: 100vh; diff --git a/src/styles/legacy.css b/src/styles/legacy.css deleted file mode 100644 index 78e9510..0000000 --- a/src/styles/legacy.css +++ /dev/null @@ -1,15 +0,0 @@ -/* Pre-redesign component rules, recolored with the tokens so the current - screens stay readable in both themes. Each redesign component task moves its - rules into its own file in src/styles/ (ADR 0001, section 6) and deletes them - here; the file goes when it is empty. Do not add new rules here. - Literal white and black are only text on crimson and video letterboxing. */ -.center { min-height: 100vh; display: grid; place-items: center; padding: 16px; } -label { font-size: 14px; font-weight: 500; margin-top: 8px; } -input { font: inherit; padding: 12px; border: 1px solid var(--line-2); border-radius: 8px; background: var(--tile-2); color: var(--ink); } -input:focus-visible, button:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; } -button { font: inherit; font-weight: 500; margin-top: 16px; padding: 12px; border: 0; border-radius: 8px; background: var(--accent); color: white; cursor: pointer; } -.error { margin: 0 0 4px; padding: 10px 12px; border: 1px solid var(--accent); border-radius: 8px; color: var(--danger); background: var(--accent-soft); font-size: 14px; } - - - - diff --git a/src/styles/post.css b/src/styles/post.css index a82a28d..c7bee35 100644 --- a/src/styles/post.css +++ b/src/styles/post.css @@ -1,7 +1,7 @@ /* * Post card, comments and the own-post menu (spec "Post card", ADR 0001). * Prefixed `post-` classes, tokens only. Every button sets margin, padding, - * font and color itself so the legacy `button` rule never leaks in. + * font and color itself so no global `button` rule leaks in. * --on-accent (white) appears only over video and on crimson faces. */ @keyframes post-rise { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } } diff --git a/src/styles/signin.css b/src/styles/signin.css index 2da8d81..74a88f5 100644 --- a/src/styles/signin.css +++ b/src/styles/signin.css @@ -100,4 +100,4 @@ } .signin-field input::placeholder { color: var(--ink-3); } .signin-form .signin-submit { margin-top: 18px; width: 100%; height: 54px; } -.signin-error { margin: 0; } +.signin-error { margin: 0; padding: 10px 12px; border: 1px solid var(--accent); border-radius: 8px; color: var(--danger); background: var(--accent-soft); font-size: 14px; } From c56addec5dea8530e66c845973887f088109a681 Mon Sep 17 00:00:00 2001 From: Cesar Alcazar Date: Tue, 20 Oct 2026 09:08:29 -0600 Subject: [PATCH 2/7] 99puxwol5: Give the feed retry buttons the outline sweep style now that legacy.css is gone --- src/components/FeedView.tsx | 6 +++--- src/components/MobileFeed.tsx | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/FeedView.tsx b/src/components/FeedView.tsx index 777951d..494f4b4 100644 --- a/src/components/FeedView.tsx +++ b/src/components/FeedView.tsx @@ -4,7 +4,7 @@ import type { ReactNode, Ref } from "react"; import { canDelete, type CardPost } from "@/lib/feed-model"; import type { DiscoverExpert, DiscoverMinnect } from "@/lib/discover"; import { Composer, type ComposerProps } from "./Composer"; -import { GrowButton, IconButton } from "./Buttons"; +import { GrowButton, IconButton, SweepButton } from "./Buttons"; import { PostCard } from "./PostCard"; import { useCompactLayout } from "./layout-context"; import { MobileFeed, type CurrentSlide } from "./MobileFeed"; @@ -142,7 +142,7 @@ export function FeedView(p: FeedViewProps) {

The feed did not load.

- +
); @@ -176,7 +176,7 @@ export function FeedView(p: FeedViewProps) { {p.loadMoreFailed ? (

The feed did not load.

- +
) : null} {p.loadingMore ? : null} diff --git a/src/components/MobileFeed.tsx b/src/components/MobileFeed.tsx index 91e55db..74e7a78 100644 --- a/src/components/MobileFeed.tsx +++ b/src/components/MobileFeed.tsx @@ -2,7 +2,7 @@ import { useCallback, useEffect, useRef, useState, type MouseEvent, type Ref } from "react"; import { canDelete, formatDuration, isPlayableVideo, relativeTime, type CardMedia, type CardPost } from "@/lib/feed-model"; -import { GrowButton } from "./Buttons"; +import { GrowButton, SweepButton } from "./Buttons"; import { HexAvatar } from "./HexAvatar"; import { PlayIcon, PostMenu } from "./PostCard"; import { VideoPlayer } from "./VideoPlayer"; @@ -438,7 +438,7 @@ export function MobileFeed(p: FeedViewProps) { {p.status === "error" ? (

The feed did not load.

- +
) : null} {p.status === "ready" && p.posts.length === 0 && !showLoad ? ( @@ -457,7 +457,7 @@ export function MobileFeed(p: FeedViewProps) { {p.status === "ready" && p.loadMoreFailed ? (

The feed did not load.

- +
) : null} {showLoad ? ( From ec3421512fa966f667bc3d15a8a045868989ee2d Mon Sep 17 00:00:00 2001 From: Cesar Alcazar Date: Tue, 20 Oct 2026 09:08:48 -0600 Subject: [PATCH 3/7] 99puxwol5: Check in the button tests that legacy.css is gone and no stylesheet fades disabled buttons --- tests/buttons.test.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/buttons.test.ts b/tests/buttons.test.ts index d2d2c34..7eb470b 100644 --- a/tests/buttons.test.ts +++ b/tests/buttons.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "vitest"; -import { readFileSync } from "node:fs"; +import { existsSync, readdirSync, readFileSync } from "node:fs"; import path from "node:path"; import { createElement } from "react"; import { renderToStaticMarkup } from "react-dom/server"; @@ -34,11 +34,21 @@ describe("SparkleButton disabled", () => { expect(body).toContain("var(--tile-3)"); expect(body).toContain("var(--ink-2)"); expect(body).toContain("not-allowed"); - expect(readFileSync(path.resolve(__dirname, "../src/styles/legacy.css"), "utf8")).not.toMatch(/button:disabled\s*\{[^}]*opacity/); + for (const f of readdirSync(path.resolve(__dirname, "../src/styles"))) { + expect(readFileSync(path.resolve(__dirname, "../src/styles", f), "utf8")).not.toMatch(/(^|[\s,}])button:disabled\s*\{[^}]*opacity/); + } expect(html(createElement(SparkleButton, { label: "Sign in", disabled: true }))).toContain("disabled"); }); }); +describe("legacy.css", () => { + it("is deleted and no longer imported, and no global button margin rule is left", () => { + expect(existsSync(path.resolve(__dirname, "../src/styles/legacy.css"))).toBe(false); + expect(readFileSync(path.resolve(__dirname, "../src/app/layout.tsx"), "utf8")).not.toContain("legacy.css"); + expect(globals).not.toMatch(/(^|[\s,}])button\s*\{[^}]*margin/); + }); +}); + describe("FlipButton states", () => { it("ready: POST plus send icon, flips to PUBLISH with the icon", () => { expect(flipLabels("ready")).toEqual({ front: "Post", back: "Publish", icon: true }); From 583e287af60285f22fc35c0f58e8006671c61e42 Mon Sep 17 00:00:00 2001 From: Cesar Alcazar Date: Tue, 20 Oct 2026 09:43:19 -0600 Subject: [PATCH 4/7] 99puxwol5: Lift small crimson like counts to 4.5:1 contrast and darken meta on the light featured slide --- src/app/globals.css | 3 +++ src/styles/mobile.css | 5 ++++- src/styles/post.css | 4 +++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/app/globals.css b/src/app/globals.css index 7a53f8c..f3c5b0f 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -16,6 +16,8 @@ --ink-2: #BFBDB8; --ink-3: #95938E; --accent: #C8141C; + /* Crimson for small text (like counts): plain crimson is 3.2:1 on the dark tiles. */ + --accent-text: color-mix(in srgb, #C8141C, white 40%); --danger: #FF6B70; --glass: rgba(18,18,21,.72); --shadow-pop: 0 10px 28px rgba(0,0,0,.5); @@ -41,6 +43,7 @@ --ink-2: #46484D; --ink-3: #686A70; --accent: #C8141C; + --accent-text: #C8141C; --danger: #B3121A; --glass: rgba(251,250,248,.74); --shadow-pop: 0 10px 28px rgba(26,28,31,.14); diff --git a/src/styles/mobile.css b/src/styles/mobile.css index e9204eb..cb905f7 100644 --- a/src/styles/mobile.css +++ b/src/styles/mobile.css @@ -234,6 +234,8 @@ padding: 70px 0 110px; background: radial-gradient(90% 55% at 50% 46%, color-mix(in oklab, var(--accent), transparent 84%), transparent 70%), var(--bg); } +/* The crimson glow tints the light page enough to drop --ink-3 meta below 4.5:1. */ +[data-theme="light"] .slide-featured { --ink-3: var(--ink-2); } .slide-feat-title { margin: 10px 24px 0; text-align: center; @@ -362,7 +364,8 @@ .dk svg { width: 22px; height: 22px; flex: none; } @media (hover: hover) { .dk:hover:not(:disabled) { background: var(--tile-3); } } .dk:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; } -.dk.dk-like-on { color: var(--accent); } +.dk.dk-like-on { color: var(--accent-text); } +.dk.dk-like-on svg { color: var(--accent); } .dk-beat svg { animation: post-beat .5s cubic-bezier(.2,.9,.3,1.4); } .dk:disabled { opacity: 1; color: var(--ink-3); cursor: default; } .btn-spark.btn-spark-fab.dk-plus { flex: 0 0 64px; width: 64px; height: 52px; } diff --git a/src/styles/post.css b/src/styles/post.css index c7bee35..4b6915a 100644 --- a/src/styles/post.css +++ b/src/styles/post.css @@ -122,7 +122,9 @@ .post-act:hover:not(:disabled) { background: var(--post-soft); color: var(--ink); } .post-act:disabled { cursor: default; } .post-like:hover:not(:disabled), -.post-like-on { color: var(--accent); } +.post-like-on { color: var(--accent-text); } +.post-like:hover:not(:disabled) .post-heart, +.post-like-on .post-heart { color: var(--accent); } .post-like-beat .post-heart { animation: post-beat .5s cubic-bezier(.2,.9,.3,1.4); } .post-act-open { color: var(--ink); background: var(--post-soft); } From 7647d785506ed24fb08a7eabfa66156a444ee5e6 Mon Sep 17 00:00:00 2001 From: Cesar Alcazar Date: Tue, 20 Oct 2026 09:43:19 -0600 Subject: [PATCH 5/7] 99puxwol5: Show native video controls on trending cards only after the first play --- src/components/MinnectMedia.tsx | 16 +++++++++------- tests/discover-rails.test.ts | 4 +++- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/components/MinnectMedia.tsx b/src/components/MinnectMedia.tsx index 4cb5494..1acb8b3 100644 --- a/src/components/MinnectMedia.tsx +++ b/src/components/MinnectMedia.tsx @@ -17,11 +17,14 @@ interface Props { * The trending card's 16:9 frame. Video answers play inline as a