Rediseño impeccable: brand mark, páginas 403/404, DESIGN.md + PRODUCT.md
Rediseño hecho en sesión aparte con el skill impeccable. Se registran las especificaciones y ajustes visuales al sistema ya en producción. Añade: - BrandMark.astro con el escudo/logo del laboratorio. - Favicon actualizado (svg + ico). - Páginas propias 403 y 404 consistentes con el sistema visual. - DESIGN.md y PRODUCT.md documentando decisiones. - .impeccable/design.json con el design system tokenizado. Ajusta componentes existentes (modales, autocomplete, layout, login, solicitudes, mis-préstamos, middleware) para alinearse a los tokens del design system. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,226 @@
|
||||
---
|
||||
name: LabPréstamos
|
||||
description: Sistema institucional UABC para préstamo de material de laboratorio — la bitácora de papel y Excel, digitalizada.
|
||||
colors:
|
||||
verde-institucional: "#00723F"
|
||||
verde-institucional-hover: "#005f34"
|
||||
dorado-uabc: "#DD971A"
|
||||
dorado-uabc-hover: "#c78614"
|
||||
superficie: "#F4F7F5"
|
||||
tinta: "#2D3748"
|
||||
peligro: "#C53030"
|
||||
typography:
|
||||
headline:
|
||||
fontFamily: "Inter Variable, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif"
|
||||
fontSize: "1.5rem (2xl) → 1.875rem (3xl) md+"
|
||||
fontWeight: 600
|
||||
lineHeight: 1.25
|
||||
title:
|
||||
fontFamily: "Inter Variable, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif"
|
||||
fontSize: "1.125rem"
|
||||
fontWeight: 600
|
||||
lineHeight: 1.4
|
||||
body:
|
||||
fontFamily: "Inter Variable, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif"
|
||||
fontSize: "0.875rem"
|
||||
fontWeight: 400
|
||||
lineHeight: 1.5
|
||||
label:
|
||||
fontFamily: "Inter Variable, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif"
|
||||
fontSize: "0.875rem"
|
||||
fontWeight: 500
|
||||
lineHeight: 1.3
|
||||
caption:
|
||||
fontFamily: "Inter Variable, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif"
|
||||
fontSize: "0.75rem"
|
||||
fontWeight: 400
|
||||
lineHeight: 1.4
|
||||
rounded:
|
||||
control: "0.5rem"
|
||||
emphasis: "1rem"
|
||||
pill: "9999px"
|
||||
spacing:
|
||||
tight: "0.5rem"
|
||||
base: "1rem"
|
||||
loose: "1.5rem"
|
||||
section: "2rem"
|
||||
components:
|
||||
button-primary:
|
||||
backgroundColor: "{colors.verde-institucional}"
|
||||
textColor: "#ffffff"
|
||||
rounded: "{rounded.control}"
|
||||
padding: "10px 16px"
|
||||
button-secondary:
|
||||
backgroundColor: "{colors.dorado-uabc}"
|
||||
textColor: "#ffffff"
|
||||
rounded: "{rounded.control}"
|
||||
padding: "10px 16px"
|
||||
button-ghost:
|
||||
backgroundColor: "transparent"
|
||||
textColor: "{colors.tinta}"
|
||||
rounded: "{rounded.control}"
|
||||
padding: "10px 16px"
|
||||
card:
|
||||
backgroundColor: "#ffffff"
|
||||
textColor: "{colors.tinta}"
|
||||
rounded: "{rounded.control}"
|
||||
padding: "24px"
|
||||
input:
|
||||
backgroundColor: "#ffffff"
|
||||
textColor: "{colors.tinta}"
|
||||
rounded: "{rounded.control}"
|
||||
padding: "10px 12px"
|
||||
---
|
||||
|
||||
# Design System: LabPréstamos
|
||||
|
||||
## Overview
|
||||
|
||||
**Creative North Star: "La Bitácora Digital"**
|
||||
|
||||
LabPréstamos is the printed loan sheet and the Excel logbook it used to feed, collapsed into one live surface. Every visual decision defends that lineage: nothing decorative, nothing that would feel out of place next to an official UABC form, but nothing that feels like a cold spreadsheet either. The system is **cálido pero confiable** — warm but reliable — and it earns the "warm" half narrowly: a gold accent, soft rounded corners, and gentle motion sit on top of an otherwise flat, administrative base.
|
||||
|
||||
The page itself stays flat and quiet — white cards on a pale green-grey surface, hairline borders instead of shadows, tabular numbers lined up like a real ledger. Depth is reserved for the two things that are genuinely *floating above* the page: the toast notifications and the mobile navigation dock. That asymmetry is deliberate — it is how the system tells the eye "this is the document" from "this is the chrome."
|
||||
|
||||
Two audiences read this bitácora differently. The alumno's default device is the phone — the catalog, the request modal, the pill-shaped floating dock are all tuned for thumbs. The admin's default device is the desktop — dense tables, a persistent sidebar, KPI tiles. Neither view degrades on the other's device; every screen ships both a table and a card-list rendering.
|
||||
|
||||
**Key Characteristics:**
|
||||
- Flat administrative base (white cards, hairline ink-tinted borders, no ambient shadow)
|
||||
- Shadow appears only on floating overlay chrome — the mobile dock and toasts — never on the page plane
|
||||
- Every status is a tinted pill: 12–15% color wash background, full-strength text
|
||||
- Tabular numbers everywhere a quantity, date, or stock figure appears
|
||||
- One typeface (Inter Variable) carrying every role through weight and size alone
|
||||
- Motion is a courtesy, not a performance: `motion-safe:`-gated, specific-property transitions, no `transition-all`
|
||||
|
||||
## Colors
|
||||
|
||||
Two institutional hues carry the whole palette under a strict 60/30/10 split — green dominant, gold as a deliberately rare accent, everything else neutral ink and white.
|
||||
|
||||
### Primary
|
||||
- **Verde Institucional** (`#00723F`): the UABC green. Primary buttons, the desktop sidebar's entire background, active nav states, focus rings, "healthy/positive" status pills (disponible, aprobado, devuelto), the login mark. This is the color of the system's authority — it appears on anything that confirms, approves, or orients.
|
||||
|
||||
### Secondary
|
||||
- **Dorado UABC** (`#DD971A`): the institutional gold. Used sparingly and only as an accent — secondary buttons, the "en préstamo" KPI tile, "mantenimiento" status pills, the logo-mark square on the sidebar/mobile header. Never the dominant color of a screen.
|
||||
|
||||
### Neutral
|
||||
- **Superficie** (`#F4F7F5`): the page background — a near-white green-grey, not pure white. Everything else (cards, dialogs, the desktop sidebar's text, dock) sits on top of it.
|
||||
- **Tinta** (`#2D3748`): body text, and — critically — the **source color for every border in the system**. Borders are never a fixed gray; they're `color-mix(in oklab, var(--color-ink) N%, transparent)` at 8–20% depending on prominence. This ties every hairline to the same ink token instead of a separate gray scale.
|
||||
- **Peligro** (`#C53030`): errors, destructive actions, and the one status that is allowed to break the tinted-pill convention (see Named Rules).
|
||||
|
||||
### Named Rules
|
||||
**The Ink-Mix Border Rule.** Every hairline border and divider is `color-mix(in oklab, var(--color-tinta) N%, transparent)`, never a literal gray hex. A border is always "ink, diluted," so it stays coherent with body text at any opacity.
|
||||
|
||||
**The Vencido Exception.** Every status pill uses the tinted-fill pattern (see Components → Badges) *except* an overdue loan ("Vencido"), which gets a solid `peligro` fill with white text — on both the table badge and, on mobile, a light danger wash across the entire card background. This is the system's one permitted alarm: reserve a solid semantic fill for the single state that genuinely needs to interrupt a scan, and only that state.
|
||||
|
||||
## Typography
|
||||
|
||||
**Body & Display Font:** Inter Variable (with `ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif` fallback)
|
||||
|
||||
**Character:** One typeface for the entire system — hierarchy comes from weight and size, never a second family. It reads as a single, consistent institutional voice rather than a "brand font + UI font" split.
|
||||
|
||||
### Hierarchy
|
||||
- **Headline** (600, 1.5rem → 1.875rem at `md:`, 1.25 line-height): page-level `<h1>`s — "Mis préstamos", "Estadísticas", the login screen's title.
|
||||
- **Title** (600, 1.125rem, 1.4 line-height): section and card headers — "Inicia sesión", "Inventario", empty-state headings.
|
||||
- **Body** (400, 0.875rem, 1.5 line-height): the default text size for the whole system — table cells, descriptions, list content. Notably small-scale throughout; this is a dense operational tool, not editorial content.
|
||||
- **Label** (500, 0.875rem): form field labels (`.label`), rendered at 90% ink opacity.
|
||||
- **Caption** (400, 0.75rem, opacity 60–80%): metadata — matrícula, inventory numbers, timestamps, hint text under fields.
|
||||
|
||||
### Named Rules
|
||||
**The Tabular Numbers Rule.** Any figure that represents a count — cantidad, stock (`disponible / total`), KPI values, dates — is rendered with `font-variant-numeric: tabular-nums`. Numbers must align like a ledger column, because that is literally what they replace.
|
||||
|
||||
## Layout
|
||||
|
||||
The system runs on Tailwind's default breakpoint (`md:` = 768px) as the single hard split between the mobile and desktop layouts — there is no intermediate tablet treatment.
|
||||
|
||||
**Desktop (≥768px):** a fixed 256px (`w-64`) left sidebar in solid Verde Institucional, full page height. It is collapsible: a hamburger button above the content toggles a `sidebar-collapsed` class on `<html>`, animated with a 200ms `translateX(-100%)`; the choice persists in `localStorage` and is applied via a blocking inline `<script>` in `<head>` before paint, so there is no collapse flash on reload. Content sits in `max-w-6xl` (data-dense admin views) or `max-w-4xl`/`max-w-md` (narrower alumno views), with `p-8` outer padding.
|
||||
|
||||
**Mobile (<768px):** no sidebar. A minimal fixed header (logo mark + user identity) sits at the top; navigation lives instead in a floating pill-shaped dock anchored to the bottom-center of the viewport, respecting `env(safe-area-inset-bottom)`. Content padding drops to `p-4` with `pb-28` to clear the dock.
|
||||
|
||||
**The Table/Card Swap Rule.** Every data-dense admin view (solicitudes, inventario, reportes) ships two complete renderings of the same data: a `<table>` for `md:block` and a `<ul>` of `.card` items for `md:hidden`. This is a structural swap, not a responsive squeeze — the mobile version is not a scrolled-sideways table, it is a genuinely different layout for the same rows.
|
||||
|
||||
## Elevation & Depth
|
||||
|
||||
The system is flat by default. Cards, buttons, inputs, and dialogs carry no shadow — only a 1px ink-mix hairline border. Depth is reserved, deliberately, for the two things that are not part of the page: the mobile dock nav and the toast stack, both of which visually float above whatever is scrolling underneath them.
|
||||
|
||||
### Shadow Vocabulary
|
||||
- **Floating chrome** (`box-shadow: 0 10px 30px -8px rgba(0,0,0,0.25)`): the mobile dock nav — a soft, diffuse shadow that reads as "hovering," combined with `backdrop-blur` and a translucent white background.
|
||||
- **Overlay notification** (`box-shadow: 0 16px 40px -12px rgba(0,0,0,0.25)`): the toast stack — same diffuse quality, slightly heavier, paired with `backdrop-blur-xl` and `bg-white/85`.
|
||||
|
||||
### Named Rules
|
||||
**The Flat Page, Floating Chrome Rule.** If an element is part of the document (a card, a table, a form), it stays flat with a hairline border. If an element floats above the document regardless of scroll (the dock, a toast), it gets a soft ambient shadow plus backdrop-blur. Shadow is the visual signal for "this is not part of the page you're reading."
|
||||
|
||||
## Shapes
|
||||
|
||||
Three radius steps, used by role rather than by component:
|
||||
|
||||
- **Control** (`0.5rem`, token `--radius-card`): the default — buttons, cards, inputs, dialogs, table containers. This is the system's baseline corner.
|
||||
- **Emphasis** (`1rem`, `rounded-2xl`): reserved for two "first impression" surfaces — the login screen's avatar mark and toast notifications. A visibly softer corner than the control radius, used to signal warmth at the exact moments the system greets or interrupts the user.
|
||||
- **Pill** (`9999px`, `rounded-full`): status badges, the mobile dock and its buttons, the pending-count chip. Anything that is a small, discrete piece of state rather than a container.
|
||||
|
||||
Borders are always hairline (1px) and always ink-mix (see Colors → Named Rules); the system has no heavy or decorative border weight.
|
||||
|
||||
## Components
|
||||
|
||||
### Brand Mark
|
||||
- A single authored glyph (`BrandMark.astro`, 24×24 viewBox) stands in for the system's identity everywhere a mark is needed: the desktop sidebar header, the mobile header, the login screen, and the 403/404 states. It reads as a loan tag with a punch-hole — a quiet nod to the physical préstamo ticket the system replaces.
|
||||
- It is a solid silhouette (not an outline stroke like the nav icons), rendered via `currentColor` so it can sit white-on-primary or tinted-on-danger without a second asset.
|
||||
- It is the product's own mark, not an institutional crest — it never stands in for an official UABC or laboratorio seal.
|
||||
- The favicon (`public/favicon.svg`) is the same glyph, colored Verde Institucional in light mode and Superficie in dark mode.
|
||||
|
||||
### Buttons
|
||||
- **Shape:** Control radius (0.5rem), 44px minimum height, `touch-action: manipulation` — every button is a comfortable tap target regardless of platform.
|
||||
- **Primary:** Verde Institucional background, white text. The system's default call to action (submit, approve, continuar con Google).
|
||||
- **Secondary:** Dorado UABC background, white text. Used sparingly — filtering actions, not primary flows.
|
||||
- **Ghost:** Transparent background, ink text, hairline ink-mix border (15%). Used for "Cancelar" / "Limpiar" — the low-commitment counterpart to Primary.
|
||||
- **Hover / Focus:** hover is a uniform `motion-safe:hover:brightness-110` filter across all filled variants (not a swap to a separate hover-color token); focus is a 2px solid outline in Verde Institucional, 2px offset. Disabled drops to 50% opacity and disables pointer events.
|
||||
|
||||
### Badges / Status Pills
|
||||
- **Style:** pill radius, `text-xs`/`text-sm font-semibold`, `px-2` to `px-2.5`, `py-0.5`.
|
||||
- **The Tinted Pill Rule.** Background = the semantic color at 12–15% via `color-mix`; text = the semantic color at full strength. Never a solid fill — with the one confirmed exception below.
|
||||
- **Semantic mapping:** disponible / aprobado / devuelto → Verde Institucional tint. mantenimiento → Dorado UABC tint (text at the `-hover` shade for contrast). baja / rechazado → ink tint (neutral, ~8–10%). **Vencido** (overdue) → the sole solid-fill exception: white text on full-strength Peligro, plus a light danger wash across the whole card on mobile.
|
||||
|
||||
### Cards / Containers
|
||||
- **Corner:** Control radius (0.5rem).
|
||||
- **Background:** white, always — the one surface color that appears identically on both the pale-green page background and the green sidebar.
|
||||
- **Border:** hairline ink-mix (10%); no shadow (see Elevation).
|
||||
- **Internal Padding:** `p-6` for standard cards and forms; `p-4` for dense KPI tiles; `p-0` when the card is a table/list wrapper (the table supplies its own cell padding).
|
||||
|
||||
### Inputs / Fields
|
||||
- **Style:** white background, hairline ink-mix border (20%), Control radius, 44px minimum height.
|
||||
- **Focus:** 2px solid Verde Institucional outline, 2px offset — the same focus treatment as buttons and links, no separate glow or border-color shift.
|
||||
- **Label:** `.label` class, 0.875rem/500 weight, ink at 90% opacity, always paired via `htmlFor`/`id`.
|
||||
- **Error:** inline `role="alert"` text in Peligro below the field, not a border-color change.
|
||||
|
||||
### Navigation
|
||||
- **Desktop sidebar:** solid Verde Institucional panel, white text at 85% opacity for inactive items, white/15% background wash for the active item, `aria-current="page"`. Collapsible (see Layout).
|
||||
- **Mobile dock:** floating pill, `backdrop-blur` + `bg-white/95`, icon-only (24×24 heroicons-outline, `stroke-width: 1.8`, `currentColor`), active item = solid Verde Institucional circle. Sign-out is visually separated by a vertical hairline divider and turns Peligro on hover.
|
||||
|
||||
### Toasts (signature component)
|
||||
- Fixed top-center overlay, `rounded-2xl`, `bg-white/85` + `backdrop-blur-xl`, floating-chrome shadow.
|
||||
- A circular color chip (36px) leads each toast: Verde Institucional for success, Peligro for error, Dorado UABC for info — each with a small stroke icon.
|
||||
- Entrance: 260ms `cubic-bezier(0.22, 1, 0.36, 1)` translate+scale+fade; auto-dismisses at 3.8s; tap anywhere to dismiss early; fully respects `prefers-reduced-motion`.
|
||||
- Survives a `location.reload()` via a `sessionStorage` queue — the system was built assuming most actions end in a reload, and the toast must not be lost.
|
||||
|
||||
### Modals
|
||||
- Native `<dialog>` element (no custom overlay library), Control radius, `backdrop:bg-black/40`, width `min(92vw, 28rem)`.
|
||||
- Focus moves to the first field on open; closes on backdrop click or the close-icon control (a drawn SVG X, never a `×` character); disabled while a submit is in flight.
|
||||
|
||||
## Do's and Don'ts
|
||||
|
||||
### Do:
|
||||
- **Do** use `color-mix(in oklab, var(--color-tinta) N%, transparent)` for any new border or divider — never a literal gray.
|
||||
- **Do** keep shadow exclusive to floating overlay chrome (toasts, the mobile dock). A new floating element earns the same shadow vocabulary; a page element does not.
|
||||
- **Do** use the tinted-pill pattern (12–15% background, full-strength text) for any new status or state indicator.
|
||||
- **Do** apply `font-variant-numeric: tabular-nums` to any new numeric quantity, stock figure, or date.
|
||||
- **Do** ship both a `md:block` table and a `md:hidden` card-list rendering for any new data-dense admin view.
|
||||
- **Do** gate all motion with `motion-safe:` and animate specific properties (`transition-colors`, `transition-[filter,...]`), never `transition-all`.
|
||||
- **Do** give every interactive control a 44px minimum tap target and `touch-action: manipulation`.
|
||||
- **Do** draw every icon as an SVG (the shared heroicons-outline language, or the `BrandMark` glyph for identity) — close controls, chevrons, and status glyphs included.
|
||||
|
||||
### Don't:
|
||||
- **Don't** stand in a unicode glyph (`×`, `›`, `✓`, emoji) for an icon — every icon is a drawn SVG, one consistent stroke and weight.
|
||||
- **Don't** add a shadow to `.card`, `.btn`, or `.input` — the system's flatness on the page plane is deliberate.
|
||||
- **Don't** introduce a second typeface. Inter Variable carries every role through weight and size.
|
||||
- **Don't** give a status pill a solid saturated fill — the tinted wash is the rule, and "Vencido" is the system's one confirmed exception, not a precedent to extend.
|
||||
- **Don't** reach for `rounded-2xl` outside the login mark and toasts; it is reserved for "first impression / interruption" moments, not a general card radius.
|
||||
- **Don't** replace the mobile bottom dock with a hamburger drawer, or the desktop sidebar with a top bar — the device-appropriate nav pattern per breakpoint is an established, deliberate split.
|
||||
Reference in New Issue
Block a user