---
name: LabPréstamos
description: Sistema institucional UABC para préstamo de material de laboratorio — un ticket de equipo, cruzado con un terminal de desarrollador.
colors:
cream: "#f4efea"
frost: "#ffffff"
chalk: "#f8f8f7"
ice: "#ebf9ff"
ink: "#383838"
pencil: "#a1a1a1"
graphite: "#818181"
primary: "#6fc2ff"
primary-hover: "#56b4f7"
secondary: "#ff9538"
secondary-hover: "#ef8526"
danger: "#f38e84"
danger-hover: "#ec7469"
danger-text: "#a83224"
positive: "#38c1b0"
attention: "#ffde00"
typography:
body:
fontFamily: "JetBrains Mono Variable, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace"
fontSize: "0.875rem"
fontWeight: 400
lineHeight: 1.5
letterSpacing: "0.02em"
label:
fontFamily: "JetBrains Mono Variable, ui-monospace, monospace"
fontSize: "0.75rem"
fontWeight: 500
letterSpacing: "0.05em"
textTransform: uppercase
rounded:
control: "2px"
spacing:
tight: "0.5rem"
base: "1rem"
loose: "1.5rem"
section: "2rem"
components:
button-primary:
backgroundColor: "{colors.primary}"
textColor: "{colors.ink}"
rounded: "{rounded.control}"
padding: "10px 16px"
button-secondary:
backgroundColor: "{colors.frost}"
textColor: "{colors.ink}"
rounded: "{rounded.control}"
padding: "10px 16px"
button-ghost:
backgroundColor: "transparent"
textColor: "{colors.ink}"
rounded: "{rounded.control}"
padding: "10px 16px"
card:
backgroundColor: "{colors.frost}"
textColor: "{colors.ink}"
rounded: "{rounded.control}"
padding: "24px"
input:
backgroundColor: "{colors.frost}"
textColor: "{colors.ink}"
rounded: "{rounded.control}"
padding: "10px 12px"
---
# Design System: LabPréstamos
## Overview
**Creative North Star: "The Equipment Tag on a Terminal Readout"**
LabPréstamos was rebuilt against a fully pinned external brief (MotherDuck's crayon-terminal-on-cream neobrutalism), translated from a marketing site's vocabulary into an operational lab tool's. The identity keeps the source system's mechanics intact — a warm cream canvas, monospace type standing in for a terminal readout, hard 2px corners, and a flat charcoal-offset shadow that never blurs — while dropping what only belonged to marketing (hand-drawn duck illustrations, scrolling marquees, testimonial cards). What replaces the duck is the product's own mark: a loan tag with a punch-hole, echoing the paper ticket this system replaced.
Depth here is binary, not a hierarchy: an element either sits flat on the page (bordered, no shadow — tables, list rows, inputs, the nav) or it's a discrete raised object that "presses" into its own shadow on hover (buttons, standalone cards, modals, the login card). There is no soft, no blur, no ambient glow anywhere in the system — every visual weight decision reads as a hard yes/no.
Color plays a stricter role here than in the source brief. Sky Crayon blue is reserved for actionable, filled controls — never for status. A teal (Mint Sketch) was pulled out of the source's decorative rainbow set and fixed as the system's "positive/available" status color, because an operational tool needs that distinction and a marketing site never did. Coral Sketch was likewise fixed as the sole danger color, with a separately darkened text variant (`--color-danger-text`, `#a83224`) for body copy, because the source coral fails AA contrast on white at normal text weight — the fill stays light and loud, the text goes dark and readable.
**Key Characteristics:**
- Cream page canvas, white card surfaces, charcoal (`#383838`, never pure black) as the universal line, border, and text color
- Every corner is 2px — buttons, cards, inputs, dialogs, badges, the brand mark's own chip. No pills, no circles, no `rounded-full` anywhere in the system
- One shadow, one behavior: `-6px 6px 0 0 var(--color-ink)`, hard-edged, zero blur, on every button, standalone card, toast, and modal — and it flattens into the element on hover/focus (`translate(-6px, 6px)`)
- JetBrains Mono Variable everywhere, 0.02em tracking, uppercase treatment on nav labels, button labels, section labels, and headlines
- Status pills and count badges are tinted fills with a matching-color 1.5px border and always-charcoal text — color differentiates via background and border, never via colored type
- Dense, repeated surfaces (tables, list-item cards, form inputs) stay flat and bordered; only discrete, single-instance elements carry the shadow
## Colors
The palette is inherited near-verbatim from the pinned MotherDuck brief; only the semantic *assignment* changes to fit an operational tool instead of a marketing site.
### Primary
- **Sky Crayon** (`#6fc2ff`): the system's only filled-action color. Primary buttons, active nav state, focused/selected chips, "Solicitar"/"Aprobar"/"Filtrar"/"Continuar con Google." Text on it is always Charcoal Ink, never white — matching every other filled control in the system.
### Secondary
- **Duck Bill Orange** (`#ff9538`): sparse accent, repurposed from the source's "illustration/marquee" role (this app has neither) into the operational tool's low-emphasis-but-real accent — "Exportar CSV," "Mantenimiento" status tint, the "En préstamo" KPI tone.
### Neutral
- **Cream Paper** (`#f4efea`): the page canvas — every screen's base layer.
- **Frost White** (`#ffffff`): card, dialog, sidebar, and nav surfaces — the raised layer on cream.
- **Chalk Gray** (`#f8f8f7`): hover wash on flat (non-shadowed) interactive rows, and the neutral badge fill for "Baja"/inactive states.
- **Charcoal Ink** (`#383838`): the universal line — every border, every default text color, the shadow color itself. Never pure black.
- **Pencil Gray** (`#a1a1a1`): secondary/muted text (labels under headings, metadata, roles) — a real token, not an opacity trick.
### Status colors (extension beyond the source brief)
- **Mint Sketch → Positive** (`#38c1b0`): "disponible," "aprobado," "devuelto en préstamo" status. Pulled out of the source's decorative rainbow-button palette because the operational tool needs a status color distinct from the primary action color; the source brief, built for a marketing site, never had this problem.
- **Coral Sketch → Danger** (`#f38e84` fill / `#a83224` text): "rechazado," "vencido," destructive actions. Split into two values because the fill color (used for badge backgrounds, borders, button fills) is deliberately light and loud, while body text needs the darker `-text` variant to clear 4.5:1 contrast on white.
### Named Rules
**The Charcoal Text Rule.** No filled or tinted surface ever carries white or colored text — text is always Charcoal Ink, full stop. Color differentiates status and action through background fill and border only. This is a deliberate tightening of the source brief, which used white nav-button text as an exception; LabPréstamos has no exception.
**The One Shadow Rule.** `-6px 6px 0 0 var(--color-ink)` is the only shadow value in the system. It never blurs, never softens, never gets a second variant for "subtle" elevation — an element either has this exact shadow or it has none.
## Typography
**Body & Display Font:** JetBrains Mono Variable (weights 100–800 available; the system uses 400/500/600), with `ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace` fallback. Chosen as the pinned brief's own named substitute for the licensed Aeonik Mono.
**Character:** One monospace face for the entire system, 0.02em letter-spacing throughout to open up the mechanical density of mono at small sizes. Uppercase tracking is reserved for structural labels (nav items, button text, form labels, section headers, the login headline) — body copy, names, and descriptions stay in normal case so real data (student names, material names) stays legible rather than shouting.
### Hierarchy
- **Headline** (600, 1.5rem → 1.875rem at `md:`, uppercase): page `
`s, the login screen's title.
- **Title** (600, 1.125rem): section and card headers, dialog titles — not uppercased by default, uppercased where it doubles as a nav/label element.
- **Body** (400, 0.875rem, 1.5 line-height): the default text size — table cells, descriptions, list content.
- **Label** (500, 0.75rem, 0.05em tracking, uppercase): every form field label (`.label`), nav items, badge text.
- **Caption** (400, 0.75rem, Pencil Gray): metadata — matrícula, inventory numbers, timestamps.
### Named Rules
**The Tabular Numbers Rule.** Any figure representing a count — cantidad, stock, KPI values, dates — carries `font-variant-numeric: tabular-nums`, inherited unchanged from the prior system. JetBrains Mono's own distinctive dotted-zero glyph reinforces the "terminal readout" reading at large KPI sizes.
## Layout
Unchanged from the incumbent structural system — the redesign is a full re-skin, not a re-architecture. `md:` (768px) remains the single hard breakpoint between mobile and desktop. Desktop keeps the fixed 256px collapsible sidebar; mobile keeps a bottom navigation bar, now a flush, flat, full-width strip (not a floating pill) with a 2px charcoal top border and no shadow — matching the source brief's own flat, unshadowed nav-button treatment. Content still ships both a `md:block` table and a `md:hidden` card-list rendering for every data-dense admin view.
## Elevation & Depth
Binary, not graduated. An element is either **flat** (a 1.5–2px charcoal border, no shadow — the default for anything dense or repeated: tables, list-item cards, inputs, the nav) or **raised** (2px charcoal border plus the one hard shadow — reserved for discrete, single-instance, actionable surfaces: buttons, the login card, modals/dialogs, toasts, KPI tiles, and clickable dashboard tiles). There is no third state, no blur, no soft ambient shadow anywhere in the system.
### Shadow Vocabulary
- **Hard** (`box-shadow: -6px 6px 0 0 var(--color-ink)`, token `--shadow-hard`): every raised element at rest.
- **Hard, pressed** (`transform: translate(-6px, 6px)`, shadow reads as `0 0 0 0`): the same element on hover/focus — it visually "presses" into its own shadow. Active state presses halfway (`--shadow-hard-sm`, `-3px 3px`) for a two-stage press.
### Named Rules
**The Press Rule.** Every raised element's hover state is the same transform: translate exactly the shadow's own offset, so the shadow disappears under the element. No brightness filter, no color darken — motion is the only hover signal on raised elements.
## Shapes
One radius for the entire system: **2px** (`--radius-card`, and Tailwind's `rounded-lg`/`rounded-2xl`/`rounded-full` are globally overridden to resolve to it). Buttons, cards, inputs, dialogs, badges, the brand mark's chip — everything is a near-square corner. There is no pill, no circle, no soft/emphasis radius tier; the prior system's `rounded-full` nav dock and status pills were converted wholesale. Borders are always 1.5–2px solid Charcoal Ink (never a tinted or literal-gray border) — the system has no hairline-border convention.
## Components
### Buttons
- **Shape:** 2px radius, 2px Charcoal Ink border, 44px minimum height, `touch-action: manipulation`.
- **Primary:** Sky Crayon fill, Charcoal Ink text, hard shadow. The default call to action.
- **Secondary:** Frost White fill (not a second brand color — the source brief is explicit that Sky Crayon is the sole filled-action color), Charcoal Ink border and text, hard shadow.
- **Ghost:** transparent fill, Charcoal Ink text, a lighter border (35% ink-mix), no shadow. Used for "Cancelar"/"Limpiar."
- **Hover / Focus / Active:** see Elevation → The Press Rule.
### Badges / Status Pills
- **Style:** 2px radius, 1.5px border in the semantic color, uppercase text at 0.03em tracking, always Charcoal Ink.
- **The Tinted-Fill-Bordered Rule.** Background = the semantic color mixed 18–25% into white; border = the semantic color at full strength; text = Charcoal Ink always. Count badges (the "N pendientes" chip beside a heading) use a solid semantic fill instead of a tint, bordered in Charcoal Ink — the one place a badge goes solid.
- **Semantic mapping:** disponible / aprobado / devuelto → Positive (mint). mantenimiento / en préstamo (KPI) → Secondary (orange). rechazado / vencido → Danger (coral). baja / neutral counts → Chalk Gray with a graphite border.
### Cards / Containers
- **Corner:** 2px.
- **Background:** Frost White, always.
- **Flat variant** (`.card-flat`, `.card`): 1.5–2px Charcoal Ink border, no shadow. Used for tables, list rows, dense repeated content.
- **Raised variant** (`.card-raised`, `.card-link`): adds the hard shadow. Used for the login card, clickable dashboard tiles, KPI tiles — anything discrete and singular rather than part of a repeated list.
- **Internal Padding:** `p-6` standard, `p-4` for dense KPI tiles, `p-0` when the card wraps a table (the table supplies its own cell padding).
### Inputs / Fields
- **Style:** Frost White background, 2px Charcoal Ink border, 2px radius, 44px minimum height. No shadow — inputs are always flat, matching the source brief's own Text Input spec.
- **Focus:** border color shifts to Sky Crayon; no glow, no ring.
- **Label:** `.label` — uppercase, 0.75rem, 0.05em tracking, Charcoal Ink.
- **Error:** inline `role="alert"` text in Danger-text below the field.
### Navigation
- **Desktop sidebar:** Frost White panel (not a colored panel — a deliberate departure from the prior UABC-green sidebar, matching the source brief's flat white nav bar), 2px Charcoal Ink right border. Active item = solid Sky Crayon chip with a 2px Charcoal border; inactive = transparent with a Chalk Gray hover wash. Uppercase labels throughout. Collapsible, same mechanism as before (localStorage + blocking inline script, no flash).
- **Mobile nav:** a flush, full-width bottom bar (not a floating pill), Frost White, 2px Charcoal top border, no shadow — flat, matching the source brief's "nav buttons are flat" rule. Active icon = a 2px-radius Sky Crayon square with Charcoal border.
- **Brand mark chip:** on colored (Sky Crayon) or panel backgrounds, a 2px-radius chip with a 2px Charcoal border; on the white sidebar/mobile header it's a translucent white wash instead, avoiding a third solid color competing with the mark itself.
### Toasts
- Frost White, 2px Charcoal Ink border, hard shadow, 2px radius (down from the prior system's blurred glass `rounded-2xl` treatment — MotherDuck bans blur and ambient shadow outright).
- A 2px-bordered color chip (36px) leads each toast: Positive for success, Danger for error, Secondary for info — Charcoal Ink stroke icon, not white.
- Entrance: 260ms translate+fade, same timing as before; still respects `prefers-reduced-motion`; still survives `location.reload()` via the sessionStorage queue.
### Modals
- Native `