Repository navigation
Designer Engine
English · Español
The designer engine is the part of proxy-core::diseno that turns one effective design into pixels: the data model, the effective-design resolver and render hash, text shaping with parley, glyph painting with tiny-skia, symbols, and the per-face painter in render.rs. Multi-piece cards (split, flip, meld…) are assembled on top of it and covered in Designer-Composition.
For concepts (CardDesign, Collection, card > collection > factory) read Designer-Overview first.
Crate path: src-tauri/crates/proxy-core/src/diseno/.
| Item | Where | Meaning |
|---|---|---|
efectivo(d, coleccion) -> DisenoEfectivo |
efectivo.rs |
Resolve card > collection > factory. |
huella(e, lang, cara, recursos) -> String |
efectivo.rs |
SHA-256 hex render key. |
Motor::de_fabrica() |
render.rs |
Per-thread typesetting state: Letras (fonts) plus a Maquetador. Loads the built-in fonts. |
Recursos { pack, simbolos, imagenes } |
render.rs |
What a render borrows: the frame Pack, the Simbolos, and an Imagenes provider. |
trait Imagenes { fn imagen(&self, blob) -> Option<Arc<RgbaImage>> } |
render.rs |
The core never reads disk; the caller supplies decoded images. SinImagenes is the empty implementation. |
render(motor, e, cara, lang, rec, card, ancho_px, salida) -> Result<Render, DisenoError> |
componer.rs (re-exported from render.rs) |
Paint one printed face. Render { imagen: RgbaImage, avisos: Vec<Aviso> }. |
render_capa(...) -> Option<CapaVista> |
componer.rs |
The card without its artwork, on transparency, plus where the artwork goes. For live artwork dragging. |
Salida::{Pantalla, Impresion} |
render.rs |
Screen: rounded transparent corners. Print: opaque, square corners (the cutter rounds them; bleed repeats the edge). |
reducida(img, lado) |
render.rs |
Downscale an artwork to at most lado px on the long side (the image the live preview moves). |
Letras::{nuevas, cargar, cargar_emoji, tiene} |
letras.rs |
Font catalogue; cargar_emoji registers the colour emoji font as the generic emoji family. |
Simbolos, SimbolosPropios
|
simbolos.rs |
Scryfall symbol SVGs and pack-own symbols. |
Dependencies (src-tauri/crates/proxy-core/Cargo.toml): parley (layout/shaping), skrifa (glyph outlines), tiny-skia (rasteriser), resvg (SVG: frames and symbols), fast_image_resize (Lanczos3 and pixel resizing), image, regex, sha2.
flowchart TD
A["efectivo(): DisenoEfectivo"] --> B["componer::render: pick Maquetacion + Cuerpo"]
B --> C["pintar_cara (render.rs): one face on a Lienzo"]
C --> C1["colour choice: colores_marco + Tonos + vars"]
C1 --> C2["fit rules text: cuerpos::ajustar, dynamic box"]
C2 --> C3["fondo layers, artwork, ventana_svg"]
C3 --> C4["pack layers: capas with si conditions"]
C4 --> C5["texts: cost, title, type, label, emblem, rules, P/T, footer"]
C5 --> D["corner mask, de_pixmap: RgbaImage + avisos"]
See Designer-Overview for the type table. Engine-relevant details:
-
FineTuning::limitado()clamps everything: offsets to +-AJUSTE_MAX_MM(3 mm);rules_box_opacityto 0..1;art_radius0..20 mm;card_radius0..6 mm; text sizes toTAMANO_TEXTO_MIN..MAX(0.5..1.6); line spacing toINTERLINEADO_MIN..MAX(0.7..1.6).efectivoalways applies it. - Title squeeze constants:
ESTRECHADO_DEFECTO0.65, rangeESTRECHADO_MIN0.55 toESTRECHADO_MAX0.75,ESTRECHADO_BASE_DEFECTO1.0. -
Avisovariants:SinTextoOficial,TextoNoCabe { hueco, sobra },TituloReducido { hueco },ReglasEditadas,FaltaNombre,LetraNoEncontrada,FaltanSimbolos,PackSinLayout,EstiloNoEnElPack,LayoutDesconocido,ColeccionPerdida,SinCinta. - Tests:
modelo.rsround-trips a two-face design, checks the 108-card deck stays under 2 MB of JSON (peso_de_un_deck_disenado), and checks that a pre-2.0DeckCardJSON still parses without adesignkey (una_carta_1x_se_lee_igual_y_no_escribe_design).
Not to be confused with src-tauri/src/diseno/borrador.rs (the app-side Scryfall-to-CardData builder, see Designer-App-Layer). The core one is pure text logic:
-
reglas_efectivas(d, cara, lang): the rules text that is painted. A hand-writtenrules_overridewins, but the original card name is still replaced by the thematic one. -
sustituir_nombre(texto, originales, propio, espanol): replaces the original names (full names first, longest first, then their short forms such as the part before the comma) by the thematic name. Whole words only (cambiar_palabra). It uses private-use marker characters so an already-substituted name is never replaced twice. In Spanish,quitar_articulosdrops the article before the substituted name (delbecomesde,albecomesa,el/la/los/lasremoved) because the thematic name is usually a character name, not an object. -
nombre_efectivo: thematic name, else the printed Spanish name (es) or the English name (en).nombre_original: all face names joined with//. -
siguiente_numero/numero: footer numbering,0001...for cards andT001...for tokens, above the highest already in the deck.
Letras wraps a parley::FontContext built with CollectionOptions { shared: false, system_fonts: false }. Only fonts passed to cargar(Vec<u8>) (TTF/OTF, variable fonts included) exist. Rationale: a card must look the same on every machine, and a missing system font must never silently change layout.
- Built-in fonts (
LETRAS_DE_FABRICAinrender.rs, viainclude_bytes!fromassets/fuentes/): Spectral Regular/Italic/SemiBold/Bold and Montserrat (variable). Their licences are alongside (Spectral-LICENSE.txt,Montserrat-LICENSE.txt). - Emoji font (
LETRA_DE_EMOJIinrender.rs): Twemoji Mozilla (COLR, solid-colour layers, about 1.4 MB; graphics CC BY 4.0, licence inTwemoji-LICENSE.txt).Motor::de_fabricaloads it withLetras::cargar_emoji, which sets it asGenericFamily::Emoji.parleyalready asks for that family whenever a cluster is an emoji (ZWJ sequences, skin tones, flags,U+FE0F), after the text family, so no text font needs to carry emoji and a card never shows an empty box for them. It is bundled (not downloaded) because emoji can appear in any text of any card. Caladea is inassets/fuentes/only as a test fixture (letras.rsandrecursos.rstests). - Imported and downloaded fonts are loaded by the app into every thread's
Motor(Recursos::con_motorinsrc-tauri/src/diseno/recursos.rs, rebuilt when the font "generation" counter changes). Font ids are the SHA-256 of the file. See Frame-Packs for the downloadable OFL catalogue. - A collection can ask for another title/rules family (
font_title,font_rules). If it is not loaded,Carta::letra_sin_pesofalls back to the pack's font and recordsAviso::LetraNoEncontrada.
-
Parsing to
Parrafos (Vec<Trozo>,Trozo::Texto { texto, cursiva }orTrozo::Simbolo):-
reglas(texto): one paragraph per line. Text inside parentheses is italic (reminder text);{X}becomes a symbol;[[word]]marks a highlight span; the short "ability word" before—at the start of a line (at most 4 words, no{ : ( . , •) becomes italic and coloured (palabra_de_habilidad). -
sabor(texto): flavour text, all italic. -
con_simbolos(texto): symbols only (type line, footer).llano(texto): plain. - Highlight and ability-word spans use private-use markers (
RESALTE,HABILIDAD), stripped inmaquetarand painted in the pack'scoloresTextocolours if the pack has them; otherwise the markers vanish and the text is the normal colour.
-
-
Maquetador::maquetar(letras, parrafo, estilo, ancho)lays one paragraph out withparley: default family/size/weight/line height, forced lining numerals ("lnum", plus"smcp"for small caps), italics as ranges, colour spans, thenbreak_all_lines(ancho)andalign.ancho = Nonemeans a single line.- Symbols are inline boxes of side
estilo.tam * LADO_SIMBOLO(0.80), gapHUECO_SIMBOLO(0.05), droppedBAJA_SIMBOLO(0.09) below the baseline. Consecutive symbols ({2}{U}{U}:) form one box with the trailing punctuation (: , . ; )) attached as a nestedBloque(Grupo.cola), so a cost never splits across lines. -
Maquetador.sustituiris a list of (char, replacement) pairs set from the pack'ssustituirmap (componer::preparar), for characters a pack font lacks.
- Symbols are inline boxes of side
-
Estilo(family, weight, size px,interlinea, colour,Alinear,versalitas,resalte,habilidad) is the paint-ready style.Bloqueis a laid-out paragraph (ancho,alto,base, plusultima_linea_ancho()). -
Fitting:
-
linea_ajustada_con_base(title and type line): see Title squeeze below. -
caja_de_reglas: stacks rules paragraphs and flavour text withSeparaciones { parrafo: 0.32, sabor: 0.75 }(multiples of the font size) and records where the divider line goes between rules and flavour. -
ajustar_reglas: if the box is too tall, binary-searches the font size down in steps of 0.1 pt (paso) totam_min; at the minimum it tightens spacing (parrafo 0.12,sabor 0.45) and, if it still does not fit, returns the overflow inAjuste.sobra.
-
pintar_bloque(lienzo, bloque, x, y, pincel, simbolos) walks the parley lines. For every glyph run it fetches the outline with skrifa unhinted (works with variable fonts via normalised coordinates), accumulates one tiny_skia path per run through the Lapiz outline pen, and fills it with anti-aliasing. Details:
-
Pincel { escala_x, color }:escala_xis the horizontal squeeze factor (text is condensed by scaling x, not by switching fonts);coloroverrides the text colour (used for the drop shadow). - Synthetic italic (
synthesis().skew()) is applied as a shear in the pen; synthetic bold draws an extra stroke of0.035 * size. - Inline boxes paint their symbols through
Simbolos::pintar; in shadow mode a symbol becomes a circle of the shadow colour. Missing symbols are returned as codes (painted grey) and surface asAviso::FaltanSimbolos. -
pintar_cajapaints a rules box and the flavour divider;tiene_glifo(datos, c)checks a font for a character. - Colour glyphs (emoji): before taking an outline, each glyph is offered to
emoji::pintar_glifo, which asksskrifafor its colour layers (color_glyphs) and paints them in place with aColorPainter(emoji.rs): per layer, a clip with the layer's glyph and a fill from the CPAL palette 0. It uses the same baseline, size andescala_xas the text. In shadow mode (Pincel.color) every layer takes the shadow colour. Limits: gradients (COLRv1) are painted with the colour of their first stop and layer compositing is ignored; Twemoji only uses solid colours. BumpVERSION_MOTORif the emoji font changes.
Simbolos holds parsed usvg::Trees by code ("T", "2/U", "W/P"), keyed by codigo() (braces stripped, upper case). Scryfall's SVGs are downloaded and stored by the app (symbols_status command, refreshed after 30 days, CADUCA_SIMBOLOS); see Designer-App-Layer. Simbolos::nuevos() always includes two built-in footer icons from assets/iconos/: {PINCEL} (brush) and {ESTRELLA} (star). The footer text maps the characters ★ and ✎ to them.
SimbolosPropios is the pack-supplied layer (SVG or PNG per code, pixel flag for nearest-neighbour scaling). Simbolos::con_propios(Arc<SimbolosPropios>) returns a view where own symbols shadow Scryfall's; codes the pack lacks fall through to Scryfall. PNG symbols are fitted without distortion, centred in the square.
pintar_cara(motor, e, lang, rec, estilo, avisos, opciones) -> Pieza paints a face on a Lienzo (a tiny_skia::Pixmap plus the mm-to-px factors kx, ky and the canvas size in mm). Everything is specified in millimetres on a 63 x 88 card (or the style's own tamano); the canvas converts. The same function paints a normal card, half of a split card, the aftermath strip, a landscape plane… because Opciones (cara, cuerpo, transparente, ancho_px, alto_px, indicador, otra_cara, sin_pie, sin_arte, aventura) and the EstiloDef passed in say what to draw.
-
Canvas.
Lienzo::nuevo(w_mm, h_mm, ancho_px, alto_px). Filled with opaque black unlessopciones.transparente. -
Colour choice.
colores_marco→eleccion_marco:-
FrameColor::Palette/Gradient/Customare taken as given. -
Auto: one card colour gives its palette; two give a gradient of the two (in order); three or more givegold; none givesartifact(type contains Artifact) orcolorless. A colourless land uses its colour identity if any (so a dual land is coloured), else thelandpalette. Face colours win over card colours. - Palettes (
PaletaDef) becomeTonos { claro, medio, oscuro, tinte, caja, tinta }; a custom colour is turned into tones by lightening/darkening; a gradient mixes the two (Tonos::mezcla). A palette missing from the pack renders grey.
-
-
Rules-box mode. From
FrameOptions.rules_box(Autouses the style'scajaPorDefecto:Tinte= colour tint at 0.80 opacity,Clara= light box at 1.0;Dark= near-black 0.85;Light= cream 0.92;Tint{hex}= 0.80). The fine-tuningrules_box_opacitypushes the opacity toward 1. The text ink (tintaCaja) is white or the palette ink depending on the perceived luminance of the box. -
SVG variables. A
BTreeMap<String,String>(vars) withdefs(the gradients) and the colours listed in Frame-Packs, later extended with the dynamic-box geometry. -
Rules text first. The body is laid out before anything is painted because the growing rules box moves the title bar and the artwork edge:
-
contenido_de_la_cara→ aContenido(plain text, sections with badges, or adventure columns; see Designer-Composition). -
Dynamic box (style has
caja): try the "comfortable" height (alto_comodo) letting the font shrink down to 75 % (LETRA_COMODA) unless the user fixed a rules size; if that does not fit, usealto_maxwith the full font and shrink as needed down to a 6 pt floor. If the last line would run into the power/toughness box, the bottom padding is raised and the fit redone. The resulting geometry becomes numeric variables for pack expressions (yReglas,altoReglas,yTipo) and SVG variables (yReglas,altoReglas,yTipo,yTipo04). Gotcha:yReglas/altoReglasmean the text area in hueco expressions (nums) but the whole box in SVGvars. -
Fixed box (no
caja): fit inside thereglashueco (minus the MDFC strip); the text is vertically centred (alinearVcan change that). - Overflow at the floor raises
Aviso::TextoNoCabe { hueco: "reglas", sobra }(mm).
-
-
Background layers (
EstiloDef.fondo) are painted under the artwork. Skipped whensin_arte(live-drag layer), because they would cover the artwork the UI places underneath. -
Artwork.
pintar_arte(l, img, hueco, framing):- No rotation: one step crop plus Lanczos3 resize (
reescalarwithResizeOptions::crop). Zoom >= 1; offsets in [-1, 1] move within the slack on each axis. - With rotation: scale up to cover the rotated rectangle, then draw with a bicubic rotation transform.
- No image: a neutral dark gradient (
sin_arte), unless the style hasfondolayers. The hueco may use box variables so the art reaches the type bar. - The result is returned to the caller as
Pieza.arte(fractions of the canvas) forrender_capa.
- No rotation: one step crop plus Lanczos3 resize (
-
Art window (
ventanaArte):ventana_svgpaints black outside the window with rounded corners (radius from the style, orFineTuning.art_radius). -
Pack layers (
Carta::capas). EachCapais skipped unless itssicondition holds for theHechos(corona/fr/cinta/emblema set here, the rest fromhechos_de). Then:-
cajaReglaslayers paint the requested box tint in their zone (tinte_caja) and nothing else; - PNG layers (
capa_png) resolve{color}/{color1}/{color2}in the path (Capa::png_para), evaluate the zone expressions with the box variables (a zone that references a variable the card lacks is skipped), and paint withpng_del_pack(full stretch) orpng_en_tramos(tramos: top and bottom slices keep proportions, only the middle stretches); blend (mezcla) and opacity apply throughpintura_con; - SVG layers are
rellenar-ed with the variables and rendered byresvgover the whole canvas (Lienzo::svg). A layer not found in the pack falls back to the builtin pack's files. - If the style has
ventanaArte.repintarand the user setart_radius, layers are split atrepintarTras: after the first group,repintar_ventanare-paints the artwork (or black) over the zones where the frame image drew a baked-in curve, then the remaining layers follow.
-
-
Texts, in this order: cost (
coste: right-aligned symbols, with a dark circle behind each unless the pack has own symbols; the title width is reduced to stay left of the cost when both are on the same row), face indicator (sun/moon/triangles for transform and MDFC, pushes the title right), title, ribbon with the original name (cinta), type line (width reduced by the label pill), label pill (etiqueta: rarity/legendary/basic land type), emblem (imagen, fitted undistorted), fullArt colour symbol, rules content (pintar_contenido) or dungeon rooms (pintar_mazmorra), Vanguard hand/life, MDFC other-face strip (franja_otra_cara), power/toughness (or loyalty, or defense;fr_texto), footer (pie). -
Warnings (missing name, hand-edited rules, no Spanish text) are added and the
Piezareturned.
Afterwards componer::render removes duplicate warnings, adds FaltanSimbolos (excluding the built-in icons), and applies the corner mask: FineTuning.card_radius when set (screen and print), else the style's radio on screen and square for print. de_pixmap un-premultiplies to RgbaImage.
Carta::linea(nombre, parrafo, ancho_max, squeeze) → linea_ajustada_con_base:
- Lay the text out on one line. The line is always squeezed to at least
squeeze_base(collection/card "minimum squeeze", 1.0 = none, only for thetituloandtipohuecos). - If it still does not fit, squeeze horizontally (
Pincel.escala_x) down tosqueeze_min(the limit, 55-75 %). - If even that does not fit, shrink the font size just enough, and report
Aviso::TituloReducido { hueco }.
Decision rationale: condensing the glyphs a little keeps the pack's font size and card look; shrinking is the last resort. Helper texts (texto_centrado, texto_izquierda, used by badges and the MDFC strip) use a fixed 0.6 limit.
Applied inside Carta::hueco, escala_texto, estilo_texto, pintar_cara and pie:
| Field | Effect |
|---|---|
title, cost, type_line, emblem, pt, footer (mm) |
Added to the hueco y (Carta::hueco). |
rules (mm) |
Added when the rules content is painted (the hueco also measures the box, so it is not moved in hueco). |
title_size, type_size, rules_size, pt_size, footer_size
|
Multiply the font size of that role (escala_texto; the ribbon follows title_size). With rules_size set the comfortable-height shrink is skipped: the box grows as needed and the font only drops if even the maximum box is too small. |
rules_line_spacing, footer_line_spacing
|
Multiply the line height / footer row pitch. |
rules_box_opacity |
See step 3. |
art_radius, card_radius
|
Corner radii (mm), see steps 8 and the corner mask. |
Image-based packs (Original, Balatro) have one PNG per colour instead of a gradient SVG. For layers whose path contains {color} only:
-
ExtraMarco::Degradado(b): paint the first palette's PNG, then the second palette's PNG withfundir_a_la_derecha(alpha ramp from 35 % to 65 % of the card width). -
ExtraMarco::Tinte(color): take the neutral (colorless) PNG andtenirit, an overlay-style blend driven by luminance that keeps highlights and shadows. -
ExtraMarco::Nada: the PNG of the chosen palette. Two-colour cards inAutostay ongold(clave_marco).
render::imagenes_png keeps two process-wide LRU lists (ORIGINALES: decoded PNGs; A_MEDIDA: resized to the exact pixel size), each capped at 160 MiB of RGBA. Keys include Pack.huella, so a modified pack never reuses old pixels. Repainting the same frame while dragging artwork therefore costs only the artwork.
Carta exposes texto_centrado, texto_izquierda, simbolos_en_fila and forma (an SVG fragment in millimetres sharing the card's gradients). cuerpos.rs uses them to draw badges (Designer-Composition).
Aviso |
Raised by |
|---|---|
TextoNoCabe |
rules text overflows at the 6 pt floor |
TituloReducido |
title/type had to shrink after squeezing |
FaltaNombre |
no thematic name for the face and language |
ReglasEditadas |
rules_override present |
SinTextoOficial |
Spanish requested, CardData.sin_texto_es
|
LetraNoEncontrada |
collection font not loaded |
FaltanSimbolos |
symbol code with no SVG/PNG |
SinCinta |
original name in ribbon requested, style has no cinta hueco |
PackSinLayout, EstiloNoEnElPack, LayoutDesconocido
|
see Designer-Composition and Frame-Packs |
ColeccionPerdida |
added by the app, not the engine |
Directory: src-tauri/crates/proxy-core/tests/ (dorados.rs, layouts.rs, comun/mod.rs) and reference images under tests/dorados/.
-
dorados.rs→dorados_de_los_casos_base: 13 base cases (legendary creature, ribbon variant, extended legendary, two-colour wall, long title, sorcery, creature in classic, artifact in borderless and classic, extended land, full-art basic, extended and classic tokens) rendered atANCHO= 420 px with the builtin pack, built-in fonts, synthetic art and synthetic symbols (comun: hand-drawn so there are no rights issues), print output. Each image is compared totests/dorados/<name>.png; a case fails at 0.5 % of pixels differing by more than 8/255 in any channel (comun::diferencia). The test also asserts noFaltanSimboloswarning. -
dos_renders_iguales_dan_los_mismos_bytes: identical inputs give identical bytes; print output is opaque; screen output has a transparent corner pixel; poker size renders at the right aspect. -
cambiar_un_color_del_pack_cambia_el_dorado: editing a palette changesPack.huellaand the image. -
tests/layouts.rs→dorados_de_los_layouts,las_cartas_grandes_salen_a_su_medida(see Designer-Composition). - Ignored, run on demand with environment variables:
tiempos(timings),original_con_sus_imagenes(PB_ORIGINAL, folder of Card Conjurer frames),original_colores,balatro_con_sus_imagenesandbalatro_contra_el_autor(PB_BALATRO,PB_AUTOR,PB_SALIDA),letras_libres_a_ojo(PB_GF),balatro_matrizinlayouts.rs. These need external assets and are for eyeballing, not CI. - Updating goldens:
PB_ACTUALIZAR_DORADOS=1 cargo test -p proxy-core --test dorados(and--test layouts) rewrites the images. Do it only for intended visual changes and review the diff; also bumpVERSION_MOTORwhen pixels change on purpose so caches refresh. - Unit tests live next to the code:
render.rs(41, covering palettes, gradients, styles, layouts, footers, tinting, sizes),componer.rs(22),cuerpos.rs(18),texto.rs,pintar.rs,pack.rs,efectivo.rs.
Also src-tauri/crates/proxy-core/examples/disenar.rs renders sample cards to disk for eyeballing, and examples/prototipo.rs is the early prototype kept as a reference (not app code).
| Failure | Behaviour |
|---|---|
| Canvas of impossible size |
DisenoError::Lienzo (pixel width is clamped to at least 16 in render; tiny-skia pixmap creation can still fail) |
| Invalid font file | DisenoError::LetraNoValida |
| Corrupt symbol | DisenoError::SimboloNoValido |
| Pack layer file missing at paint time | the layer is skipped silently (packs are validated on load, so this means a builtin-fallback case) |
| Style missing from the pack | builtin pack's style is used; then the pack's borderless; finally DisenoError::Lienzo
|
Use and build · Uso y desarrollo
- User-Guide · Guía de usuario
- Development-Setup · Preparación del entorno de desarrollo
- Testing-and-CI · Tests y CI
- Releases-and-Auto-Updates · Versiones y actualizaciones automáticas
- Conventions · Convenciones
Architecture · Arquitectura
- Architecture · Arquitectura
- IPC-and-Error-Handling · IPC y manejo de errores
- Rust-App-Layer · Capa de aplicación Rust
Data · Datos
- Deck-Model · Modelo del mazo
- Storage-and-Blobs · Almacenamiento y blobs
- Deck-Package-Format · Formato del paquete de mazo
- Deck-Library · Biblioteca de mazos
Getting cards · Conseguir cartas
- Decklist-Parsing · Parseo de la lista del mazo
- Scryfall-Integration · Integración con Scryfall
- External-Sources · Fuentes externas
- Card-Identification-and-OCR · Identificación de cartas y OCR
Layout, images, PDF · Maquetación, imagen y PDF
- Layout-Engine · Motor de maquetación
- Imaging-and-PDF · Imagen y PDF
- Export · Exportación
- Live-Preview · Vista previa en vivo
- Statistics · Estadísticas
Card designer · Diseñador de cartas
- Designer-Overview · Visión general del diseñador
- Designer-Engine · Motor del diseñador
- Designer-Composition · Composición del diseñador
- Frame-Packs · Packs de marcos
- Designer-App-Layer · Capa de aplicación del diseñador
- Designer-UI · Interfaz del diseñador
- Card-Editor-Dialog · Diálogo Editar carta
Game table · Mesa de juego
Frontend · Frontend
- Frontend-Architecture · Arquitectura del frontend
- State-Stores · Stores de estado
- Internationalization · Internacionalización
- Themes-and-Skins · Temas y skins
- Settings-and-Shell · Ajustes y shell
- Tutorials · Tutoriales
- Decklist-Panel · Panel de la lista del mazo
- Add-Card-and-Variants · Añadir carta y variantes
- Set-Browser · Explorador de sets
Reference · Referencia