Skip to content

Tier 3 readability + responsiveness refactor#67

Merged
felipebalbi merged 5 commits into
OpenDevicePartnership:mainfrom
felipebalbi:tier3-refactor
May 15, 2026
Merged

Tier 3 readability + responsiveness refactor#67
felipebalbi merged 5 commits into
OpenDevicePartnership:mainfrom
felipebalbi:tier3-refactor

Conversation

@felipebalbi
Copy link
Copy Markdown
Contributor

Depends on #66

Tier 3 of the readability / responsiveness refactor. Five commits, one per task, each independently reviewable. No new dependencies; behaviour preserved aside from the deliberate responsive-layout improvements documented per commit.

Commits

  • t17team_grid: minmax(180px, 1fr) auto-fit grid with clamp() gap, drops hard-coded 240 px desktop padding.
  • t16ImageButton rewritten as a class-driven component with declarative aspect-square + max-w-[…]; per-instance <style> injection (with !important mobile overrides) is gone. Hero images are now squares with rounded-3xl / rounded-r-3xl corners; the project-introduction overlay text is forced white via !text-white so it stays legible against the SVG.
  • t14 — Replaces md:w-[Npx] paired column widths with md:flex-1 (or lg:flex-1 / lg:flex-[2] for the welcome-video row) across landing, projects, community, main, and the three team pages. Brand-asset sizes (header logo, footer marks, doc icons) and the already-responsive announcements sidebar are intentionally untouched.
  • t15 — Section gutters get a real ladder: px-4 sm:px-8 md:px-16 lg:px-32 instead of the single px-2 → md:px-32 jump. projects_component's md:py-32 likewise becomes md:py-20 lg:py-32. Header layout (logo size, hamburger, full nav, hero CTAs) shifts from md: to lg: so the desktop layout no longer fights for room at 768 px.
  • t18 — Mobile nav a11y + dismissal: aria-expanded/aria-controls/dynamic aria-label on the burger, aria-current="page" on the active link, aria-label="Primary" on both <nav>s, ESC-to-close via window_event_listener, click-outside via a fixed inset-0 backdrop, and tap-a-link-closes via a new on_navigate callback prop on NavButton / ExternalNavButton. ExternalNavButton also picks up rel=\"noopener noreferrer\".

Verification

  • cargo check clean after every commit.
  • leptosfmt --check src clean over all 32 .rs files.
  • dos2unix run on every modified file (no CRLF in the tree).
  • Manually verified at 320 / 480 / 640 / 768 / 1023 / 1024 / 1440 / 1920 px. Hamburger now switches at lg so the 5 nav buttons no longer compete with the logo at 768 px.

felipebalbi and others added 5 commits May 15, 2026 09:53
Rewrite the `.grid-container` block in `style/tailwind.css` for
the team / steering-committee tiles so it reflows naturally:

  * `minmax(150px, 1fr)`  ->  `minmax(180px, 1fr)` so each tile
    has a small margin around the 150 px `.member-image` portrait.
  * `grid-gap: 150px`      ->  `gap: clamp(2rem, 4vw, 6rem)`.
    The static 150 px gap dominated tablets and small laptops; the
    clamp interpolates from 32 px on phones to 96 px on wide screens.
  * Drop the `padding: 0px 8px` and the `@media (min-width: 768px)`
    block that added `padding-left/right: 240px` on desktop. The
    wrapper call site (`team_grid.rs`) already declares horizontal
    padding via `px-2 md:px-32`, so the CSS rule was double-padding.
    Removing the inner padding lets the auto-fit math use the full
    available width that the call site allots.

Net effect: the team grid uses one more column on wide desktops and
considerably less wasted gap space on tablets, with no media queries.
Tile minimum width is large enough that it falls back to one column
under ~360 px viewport.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Refactor `ImageButton` so its sizing is purely declarative via Tailwind
utilities and the per-instance `<style>` tag is gone:

  * Old props: `width`, `height`, `mobile_width`, `mobile_height`
    (numeric pixel values used by `format!()` to inject inline styles
    + a `<style>` block with an `alt`-attribute selector and
    `!important` overrides for the mobile media query).
  * New prop: `class` (defaults to `aspect-square w-full`). The
    image is always `w-full h-full object-cover`; the wrapper carries
    `aspect-ratio` and the call site sizes the image by sizing the
    enclosing flex/grid cell. No more `<style>` tag, no more
    `!important`, no more selector-by-alt-attribute.

Update call sites to use relative sizing instead of fixed pixel caps:

  * `landing_page.rs`: the three landing tiles wrap in
    `grid grid-cols-1 md:grid-cols-3 gap-16` so each tile occupies
    one third of the row at `md` and above, full width below.
  * `projects_component.rs` (3 cards): pass
    `class=\"aspect-square md:basis-1/2 shrink-0\"` so the image
    takes half of the row on desktop. The intermediate
    `<div class=\"... md:w-[600px] md:h-[518px]\">` wrapper is
    removed because the component now sizes itself.
  * `project_introduction.rs` (project hero): wrapper becomes
    `md:basis-1/2 aspect-square`. Inline-style declarations for
    `flex-shrink`, `position`, `transform`, `object-fit`, and
    the per-corner border radii are folded into Tailwind utilities
    (`flex-shrink-0`, `-translate-y-1/2`, `rounded-r-[40px]`,
    `object-cover`).

Net effect: every hero image is now a square that scales fluidly with
the viewport instead of snapping at a single `md:` breakpoint to a
hard-coded pixel size.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The two- and three-column section layouts hard-coded their child
widths in pixels (`md:w-[800px]`, `md:w-[650px]`, `md:w-[700px]`,
`md:w-[600px]`, `md:w-[400px]`, `md:w-[950px]`,
`md:max-w-[900px]`, `md:w-[423px]`, `md:w-[1200px]`). At any
viewport between `md` (768 px) and the parent's max width the columns
either overflowed the row or stranded whitespace, depending on the
section's outer padding.

Replace the pixel widths with `md:flex-1` (or `lg:flex-1` for the
welcome/video row) so each column claims an equal share of the
available row width and the columns reflow with the viewport:

  * `landing_page.rs` -- hero (800/650 split) and the three Value
    Proposition cards (400 each) are now equal flex children.
  * `community_teams.rs` -- intro 950/900 split is now equal flex
    children; dropped the inline `style="flex: 1;"` (now redundant).
  * `projects_component.rs` -- "System Firmware Domains" 700/600
    split is now equal flex children.
  * `main.rs` -- the welcome text (423 px) and embedded video
    (1200 px) row is now `lg:flex-1` / `lg:flex-[2]` so the video
    gets twice the width of the descriptive copy at lg+.
  * `team_patina.rs` / `team_ec.rs` / `team_ec_services.rs` --
    "Meet the team" 700/600 splits are now equal flex children.

Header/footer logo sizes, doc-section icon sizes, the announcements
sidebar (already using a responsive `lg/xl` ladder), and the two
`main.rs` 478 px CTA buttons are intentionally left as fixed-pixel
sizes -- they encode brand asset dimensions or already-responsive
ladders, not arbitrary column widths.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Section horizontal padding was a single jump from `px-2` (8 px) to
`md:px-32` (128 px) at exactly 768 px. Below 768 px the content
hugged the viewport edges; immediately above 768 px the gutters
suddenly stole 256 px, leaving narrow tablets cramped. There was no
intermediate step.

Replace `px-2 md:px-32` (and the matching `px-4` / `px-6`
variants) with the ladder `px-4 sm:px-8 md:px-16 lg:px-32`: 16 px on
phones, 32 px on large phones (>= 640 px), 64 px on tablets
(>= 768 px), 128 px on desktops (>= 1024 px). Section vertical padding
that was paired with `md:py-32` in `projects_component` likewise
becomes `md:py-20 lg:py-32` so the 128 px vertical gap doesn't kick
in until desktop.

Touched: every section that used the `md:px-32` pattern --
`landing_page`, `projects_component`, `community_teams`,
`partners_grid`, `team_grid`, `documentation_training`,
`header`, and the three `team_*` pages.

Footer stays on its tighter `px-2 md:px-16` ramp because its
content is a single horizontal bar that doesn't need desktop-class
gutters.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The mobile nav was a single signal-driven flyout with no accessibility
affordances and no dismissal paths beyond clicking the hamburger
again. Add the missing pieces a screen reader / keyboard user
expects:

  * Hamburger button now exposes `aria-expanded` (bound to the
    `menu_open` signal), `aria-controls` pointing at the flyout's
    new `id="primary-mobile-nav"`, and a dynamic `aria-label` that
    flips between "Open menu" / "Close menu".
  * Both `<nav>` regions get `aria-label="Primary"` so assistive
    tech can name them.
  * The active-route detection that already drives the
    `odp-header-btn-active` styling now also emits
    `aria-current="page"` on the matching `<A>`.
  * Pressing **Escape** while the flyout is open closes it
    (`window_event_listener(ev::keydown, ...)`).
  * Clicking outside the flyout closes it -- a transparent backdrop
    `<div class="fixed inset-0 z-40 lg:hidden">` is rendered when
    the menu is open and dismisses on click. Flyout sits on `z-50`
    so it stays above the backdrop.
  * Tapping any link inside the flyout closes it. `NavButton` and
    `ExternalNavButton` gained an optional
    `on_navigate: Option<Callback<()>>` prop that fires from the
    underlying `on:click`; the call sites in the mobile nav pass a
    closure that flips `menu_open` to `false`. Desktop nav passes
    no callback so its behaviour is unchanged.
  * `ExternalNavButton` now sets `rel="noopener noreferrer"` to
    fix the long-standing reverse-tabnabbing risk on the Library
    link.

The desktop / mobile breakpoint switch (now at `lg` after t15) is
left in place. The plan's "compact nav at lg, full nav at xl" idea is
intentionally skipped: with the current label lengths the full nav
fits cleanly at `lg` and a separate icon-only ladder would add
maintenance burden without a real visual win.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@felipebalbi felipebalbi merged commit 1444dc8 into OpenDevicePartnership:main May 15, 2026
3 checks passed
@felipebalbi felipebalbi deleted the tier3-refactor branch May 15, 2026 17:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant