Eagles I
Our top team plays competitive league hockey against the strongest DPL sides and is our entry at the Armed Forces Alpine Classic. We expect players to attend most practices and all league games.
The visual system behind kmceagles.org. Every value here is a CSS custom property in tokens.css; components are plain HTML and CSS with no framework. Corners are square throughout.
Brand colors are fixed; surface and text colors switch with the theme, which follows the device's light or dark setting.
--brand-navy#0A2342--brand-red#C8102E--brand-ice#93C5FD--brand-gold#FBBF24--bg--surface--text--muted--primary--accent--link--border--border-subtle--errorHeadings: Barlow Condensed 600/700, uppercase at level one. Body: the system font stack. Major-third scale from 0.8rem to a clamped 3.052rem, with one step below it, Label (0.7rem), for short words in capitals. Breadcrumbs set the display face at 0.89rem. Body line height 1.6, headings 1.15. Rosters use tabular numerals. Every size comes from these tokens (--fs--2 to --fs-5); only display numerals, such as a jersey number, are larger.
Heading one — 3.052rem
Lead paragraph — 1.25rem. Ice hockey for the Kaiserslautern Military Community.
Body — 1rem. The KMC Eagles are a volunteer-run amateur ice hockey club serving Ramstein, Kaiserslautern, Landstuhl, Baumholder and Zweibrücken.
Small — 0.8rem. Used for metadata, captions and legal lines.
Label — 0.7rem, capitals: a card's facts, a calendar's hours
19 · 27 · 77 · 88 tabular numerals
4px base: 4, 8, 12, 16, 24, 32, 48, 64. Containers 42rem, 72rem and 90rem. Breakpoints at 40rem and 64rem add columns and spacing only; one at 22.5rem moves a visitor's Install from the header into the menu on the narrowest phones. Minimum tap target 44px; primary actions 48px.
Every button is the same height. A ghost button on its own is a link with room to press it, such as "View all events" beside a section's heading.
A button says what pressing it does, beginning with a verb, so that it reads well on its own, out of its context, as a screen reader may read it.
Two or more buttons together (.btn-row) are always the same width. When the whole group fits on one line they stand side by side, each 12rem wide (10.5rem in a group of three or more), or as wide as its words where they are longer, so a button's words never break onto a second line; when it does not, they are stacked, one under the other: the full width on phones, at most 24rem on wider screens. The browser works this out from the room there is and the number of buttons, so a group never ends in a ragged line, in a card or on the page. A ghost button in a group takes the secondary style. A list that is always stacked, such as a member's links in the menu, uses .btn-stack: every button the full width of the list, even one alone.
A button that says what pressing it will do, such as Save note, Save changes and Remove note, or Check in and Checked in, holds all its labels from the start (.swap), and only the current one is seen and read out. The button keeps the width of its longest label, so neither it nor the text box beside it moves when the words change.
Home Away Canceled Goalie needed practice C A G Retired W 4–2 L 1–3 T 2–2
Captain, alternate and goalie badges sit after a player's name; result badges show a final score on games.
On a phone the date is a line at the top of the row, "WED 14 OCT", with the tags beside it, so the title, details and counts below have the full width. From 40rem the date is a block at the left. The Schedule's cards follow the same rule.
These names are made up. Real rows link to the player's profile; a player without a headshot shows initials.
Our top team plays competitive league hockey against the strongest DPL sides and is our entry at the Armed Forces Alpine Classic. We expect players to attend most practices and all league games.
Our team for developing and recreational players, with a full league schedule in a lower DPL division. New arrivals start here, and players move up to Eagles I as rosters shift.
Surface background, square corners, subtle shadow.
The whole card is the link; the accent bar marks it as clickable.
Board members and team staff.
Used on the schedule, team and club pages, the members' home page, Your stats and Club dues. A figure with nothing to count (no players yet, no games played) is left out rather than shown as zero. A figure can be a link (the admin desk, the number to answer in Your stats): the whole cell is the link.
The panel's form or list goes here.
Open: the arrow points down.
The answer.
Every tool, form and list that opens in place is a panel: a frame, a bold title with an optional line under it, and the same arrow at the right, pointing down once open. The FAQ's questions carry the same arrow.
A choice between a few options, radio or tick box, is a framed row with a 20px control, the chosen one outlined; an "i" can sit at its right. Lists of people with something to do are rows divided by a line, with small secondary buttons at the right. A filter is always a row of chips, never a set of joined buttons; joined buttons (In and Out) are for answers.
A section's heading, with a link to the whole list beside it (under it on phones). Used on the home pages, team pages and Sub opportunities.
An area's views under the page's title, each a page of its own: the Schedule's and the Teams' members' pages. Shown only to logged-in members, each tab to those it is for; on a phone a long label gives way to its short form.
This page's own contents show the component: on a phone, the line under the breadcrumbs; on a computer, the column on the left.
A page whose reader moves between several sections has one list of them, "On this page", made by the contents macro (macros.njk): the members' home page, event pages, team pages, player profiles (on a phone or tablet), Settings, Your profile, Your stats, Club setup, the three guides, Features, Join, Getting started, the FAQ, Positions, Volunteer, the club page, the history, the media pack, the technology page, the privacy policy, the Impressum, the accessibility statement and this page. On a phone or tablet it is a line that stays under the breadcrumbs and names the section being read; pressing it opens the whole list over the page, and choosing a section closes it. On a large screen the list stands in a side column that stays in view, or leads a side column that already does, with the section being read marked by the red rule; pages of wide card rows (team pages, the club page, the technology page, Your stats) keep the line instead. An event page has one bar under the breadcrumbs, the full width of the screen, at one height and on one background: the line, and once the card's own heading has scrolled away, the event's date, kind and title in place of the words "On this page"; on a computer the bar shows whole at that moment, the event over the left column and the line over the right, naming for members the parts of that column. An entry whose section the page has hidden is left out. The long guides number their entries. A page never opens with a row of boxed links or chips to its own sections.
Point at, focus or tap these: PTS, C, Not logged in yet.
A small dark box beside the element (tips.js), above it or, without room, below, with an arrow, inside the screen and over open windows. Any element with data-tip has one; the browser's own title text becomes one too, and a button or link that shows only an icon (a close cross, the calendar's arrows) shows its label. Tips marked data-tip-help are explanations, hidden with the "i" buttons when a member turns help off. Charts show their readouts in the same box.
Where they belong: abbreviations and badges (GP, C, G); every More button, saying what the menu holds (pageMenu's tip); each view tab, saying what the view shows; column heads whose word is short (Usual no., Notices); the figures of a count line that need a word more; a short time ("Tue") with its full date; a button whose effect is not plain from its word (Accept: "Make this change on the website now"). A tip adds to what is on screen and never repeats it, and nothing a member must know lives only in a tip.
Hover cards: point at Jon Ajinga, or focus the link.
A link to a player's profile shows their card (photo, number, name, positions, team, hometown, and below them, two to a row, the facts of the profile page and the start of the bio), and a link to an event shows the event (what, when in German time, where, who, the score and, for a member, the counts and their own answer), from /data/cards.json. A name that is not a link carries data-card-person (or data-card-event, -opponent, -rink or -team) and shows its card on a tap too, with a link to the page; on an event card, which is a link itself, the names show their cards under the pointer, in every list, menu and the calendar. A plain link shows no card where the row shows the same already, on buttons or in the menus. The pointer may move onto a card. On a phone or tablet, the first tap on a name or link with a card shows the card and a second tap goes on; pressing and holding a button, tab or icon shows its tip, but never a close button's.
Markers on event cards: Notes. Bring the white jerseys.Comments. 3 comments, 2 new.Duties. Pucks, you; Drinks, open.
Keys: G H goes home; Keyboard shortcuts lists the rest.
A key is written in a kbd box, as in search and the list of shortcuts (keys.js). A control with a key carries data-key and aria-keyshortcuts, and its tip names the key after its words ("Next month · →"). Single keys never act while the reader types, and can be turned off.
Beside the tags of a member's coming event (attendance.js, "Markers"): one icon alone for each thing the event has besides the answers, always in the same order, each named for screen readers and with its tip. The small red number counts what calls for a look or a hand (new comments, open duties, players looking for a ride); the club's red marks what concerns the member. A click opens that part of the event page; on a phone, the first tap shows the tip.
Standard notice with the primary left border.
Error notice.
Gold notice for attention without alarm.
Empty state: one plain sentence saying what will appear here, such as “The roster for the current season has not been published yet.”
A notice can hold a link or bold words, and its words flow as one paragraph beside the colored rule.
A page never says Loading. A members' page that fetches its content keeps its message empty (<p class="notice" data-loading></p>) and, only if the content takes longer than a moment, shows quiet gray blocks in its place; a line still waiting for its words shows a gray bar (.skel-line). A message such as Log in first takes the blocks' place, and the page's script hides the message once the content is drawn. Whatever appears late keeps its room from the start, so nothing above it moves.
An explanation, such as who sees a note or how a tool works, goes in a round "i" beside the heading or label it belongs to (infoPop, the texts in Page text › Help buttons), never in a paragraph under it, so that pages stay short. Each "i" ends with a secondary button to the matching part of the user guide, with the guide's icon. The "i", the More menus and the share menus open as a window in the middle of the screen, like the calendar's pop-ups, wherever their button is. The menu opens as a full page: the whole screen on a phone, a full-height panel at the right on wider screens. Empty states and the message after an action stay on the page.
One glossary, one icon for each meaning (src/_data/icons.json): a page always draws an icon by its meaning, never by its picture, so the same pencil means Change everywhere. Words come first. An icon stands alone only where its meaning is universal (close, the menu, search, previous and next, back to top, the "i", change, share, zoom and full screen) or where it belongs to a small set that members learn and that names itself when pressed (the tab bar, the markers on event cards, an emergency contact's call, text and share, every More and a roster row's Options); such a control has its label (aria-label) and its tip. A few controls show their icon beside their word and drop the word only where a row has no room, so that nothing wraps: Add an event beside a title on a phone, and a visitor's Install on a computer. Beside its word an icon is silent. Icons mark places and actions, never content: titles, In and Out, statuses, event types, figures, labels, empty states and the footer stay words. Three sizes (16, 20 and 24px), a 1.75px stroke at every size, and the colour of the words around it. The Google and GitHub marks, on Log in and on Link Google and Link GitHub under Settings › Sign-in, are the only brand marks. Lucide, from the lucide-static package; npm run check:style holds every page to these rules.
Each meaning, its icon, and whether it may stand alone. The rest always sit beside their word.
closeAlonemenuAlonesearchAlonepreviousAlonenextAloneback-to-topAloneinfoAloneguideWith its wordkeysWith its wordhomeAloneeventsAloneteamsAloneinboxAlonelanguageWith its wordnotesAlonecommentsAloneridesAlonedutiesAlonelineupAloneplayer-detailsAlonesharpeningAlonearrive-byAloneroomAlonewaiting-listAloneliveAlonevideoAlonecallAlonetextAloneshareAloneaddWith its wordnew-eventAlonemany-eventsWith its wordleague-tableWith its wordadd-to-calendarWith its wordsubscribeWith its wordschedule-changeWith its wordseasonsWith its wordchangeAlonedeleteWith its wordprintWith its worddownloadWith its wordcopy-linkWith its wordcopyWith its wordemailWith its worddirectionsWith its wordrinksWith its wordlog-inAlonelog-outWith its wordinstallAlonepasskeyWith its wordnotificationsWith its worddeviceWith its wordawayWith its wordgoalieAlonegoalie-foundAlonesubsWith its wordleavingWith its wordyour-dataWith its wordphoto-consentWith its wordclub-rulesWith its worddocumentsWith its wordprofileWith its wordstatsWith its wordduesWith its wordkittyWith its wordnew-playerWith its wordmentorWith its wordequipmentWith its wordkit-ordersWith its wordtripWith its wordbank-statementWith its wordcostsWith its wordsettingsWith its wordfeedbackWith its wordtestimonialsWith its wordattendanceWith its wordprofile-requestsWith its wordadd-peopleWith its wordgroup-chatsWith its wordpollsWith its wordgearWith its wordannouncementsWith its wordclub-setupWith its wordfeaturesWith its wordmenu-linksWith its wordchecklistWith its wordactivity-logWith its wordset-answersWith its wordmaybeWith its wordanswer-byWith its wordwait-orderWith its wordoutside-guestWith its wordplayer-of-the-gameWith its wordgame-sheetWith its wordresultsWith its wordnewsWith its wordclub-yearWith its wordemergencyWith its wordhistoryWith its wordcolumnsWith its wordsaved-viewWith its wordselectWith its wordbirthdayWith its wordfew-inWith its wordwebsite-healthWith its wordwhats-newWith its wordlate-outWith its wordtime-zoneWith its wordzoom-inAlonezoom-outAlonefullscreenAloneoptionsAlone